how to apply the condition in django model - django

I have some model class like.
class user(models.Model):
Student = 's'
Hostel = 'h'
Pg = 'p'
type_of_user = (
(Student, 'Student'),
(Hostel, 'Hostel'),
(Pg, 'PG')
)
u_type = models.CharField(max_length=1, choices=type_of_user, default=Student)
and i have another class
class student(models.Model)
s_id = models.ForeignKey(user, on_delete=models.CASCADE)
but i apply the condition on s_id (show only that user where u_type=student)

what #dirkgroten just said is actually one of the possible solution to add condition but there is possible to add model field level validation. Django allow to add custome validation function in model field level link . And also if you are using serializer add custom validation there also another possible solution.

Related

Create forms from model, save to another

I'm building a survey-type app, where the questions are entered/stored in a model (by an admin). I want to use this model to auto-create a user facging form (the response will be stored in another model.
class Question(models.Model):
question_text = models.CharField(max_length=150)
questionnaire = models.ForeignKey(Questionnaire) # 'lump' questions together
class Response(models.Model):
question = models.ForeignKey(Question)
response_text = models.CharField(max_length=150)
user = models.IntegerField() # used to record user ID
I'm not sure what's the correct approach - using a ModelForm (populating through init) or a 'regular' form - where I'm not sure how I output my results - using print or adding to a form property.
Thanks.
In your init you can
self.fields['your_field']=forms.ModelChoiceField(queryset=YourQuerySet.objects.get(pk=X)) // alternatively a filter with first()
to enforce the initial foreign key object

Remove ForeignKey relationship

I want to remove the relationship between BUser and Profile:
Since the ForeignKey doesn't allow null values I have to iterate (performance is awful!) like this to remove all the relations:
for u in user.profile_set.all():
u.delete()
class Profile(models.Model):
user = models.ForeignKey('BUser')
class BUser(AbstractBaseUser, PermissionsMixin):
username = models.CharField(max_length=40, unique=True)
There is another way to delete all the relations [with a better performance]?
I've tried with:
obj.transparentprofile_set = None
obj.transparentprofile_set.clear()
obj.transparentprofile_set.empty()
but, like I said, since there's not null=True in the ForeignKey I can't use them.
You may use my way, instead touching related model via dotted ORM childs etc objects.childs_set, its more clear and human readable code:
# Get user instance
user = User.objects.get(pk=<uid>)
# Remove profiles
Profile.objects.filter(user=user).delete()
Also, you need remember about related_name Model parameter, so instead profile_set you can use:
class Profile(models.Model):
user = models.Foreignkey(
to=User,
related_name='profiles'
)
# Use related name alias in code
profiles = user.profiles.all()
profile = user.profiles.filter(pk=<profile_id>)

How do I use a ModelManager on a Django ManyToMany through field?

Let's say I have the following models:
class Poll(model):
title = models.CharField()
class Option(model):
title = models.CharField()
polls = models.ManyToManyField(
Poll,
through='PollOption',
null=True,
blank=True,
related_name='options'
)
class PollOptionManager(models.Manager):
use_for_related_fields = True
def get_queryset(self):
return super(PollOptionManager, self).get_queryset().filter(
is_active=True
)
class PollOption(model):
poll = ForeignKey(Poll)
option = ForeignKey(Option)
is_active = BooleanField(default=True)
objects = PollOptionManager()
When I try to query Poll.options.all() I'm still getting Option instances for which PollOption.is_active is False. How can I get my model manager to appropriately filter my ManyToMany relationship based on a flag on the through field?
The problem is that the through model's (related) manager is never actually used in your scenario. In order to utilize the custom manager, you have to explicitly use it, e.g.:
class Poll(models.Model):
#property
def active_options(self):
return Option.objects.filter(id__in=self.polloption_set.values_list('option'))
Here, polloption_set filters out inactive options as intended. This, however, makes the manager kind of pointless because you can just as well put the extra filter in the custom property.

Django Rest framework serializer exclude foreign key with depth 2

I have made an api that returns an object as json data. I Am using the django-rest-framework and its serializer. Using the resources (ModelResource) I excluded some fields, like a property called 'owner'. One of the fields is a foreignkey to itselve. I want to show this field in the api (so I use depth=2), but I want to exclude the same fields as I excluded in the object returning.
Is there a nice way to do this (I have tried several things without the wanted result).
This is my (simplified) code:
in models.py:
class MyObject(models.Model):
name = models.CharField(max_length=256, blank=True)
parent = models.ForeignKey('self', blank=True, null=True, default=None)
and_some_otherfields = models.otherFields(....)
owner = models.ForeignKey(User, null=True, blank=True, related_name='myobject_owner')
in resource.py:
class MyObjectResource(ModelResource):
model = MyObject
exclude = ('owner','and some other fields',)
and in the view used to return the object it returns this:
data = Serializer(depth=2).serialize(my_object)
return Response(status.HTTP_200_OK, data)
In the response it leaves out the exclude fields (as I wanted and expected).
but in the field parent, the parent myobject with all fields I want to hide.
I Am looking for a way to indicate that for this parent object, the serializer should use the same Resource, or add the secundary fields to the exclude list....
If I use depth =1 it only shows whether it has a parent ([]), or null if not, and i do need to know at least the parent's ID.
Ah, i just found it:
I need to add in the resource for all fields I want to show what resource....
fields = ('name', ("parent","MyObjectResource") , 'and all the other fields you want to see as well...')
I found it here: google groups forum question
You can skip the exlude, it ignores it, and just add the fields you want to show, you do not have to define them, unless you need to indicate what resource to use.
So following is the final code of the resource.py part:
class MyObjectResource(ModelResource):
model = MyObject
fields = ('name', ("parent","MyObjectResource"), 'and all the other fields you want to see as well...')
Here is how an other solution could be.
class ProToPicturesSerial(serializers.ModelSerializer):
pro_pictures = PictureSerializer(many=True)
pro_videos = VideoSerializer(many=True)
city_pro = CitySerializer(many=True)
class Meta:
model = Province
fields = ('id', 'name', 'intro', 'description', 'display_url', 'pro_pictures', 'pro_videos', 'city_pro')

Django Form with no required fields

I want to make a form used to filter searches without any field being required. For example given this code:
models.py:
class Message(models.Model):
happened = models.DateTimeField()
filename = models.CharField(max_length=512, blank=True, null=True)
message = models.TextField(blank=True, null=True)
dest = models.CharField(max_length=512, blank=True, null=True)
fromhost = models.ForeignKey(Hosts, related_name='to hosts', blank=True, null=True)
TYPE_CHOICES = ( (u'Info', u'Info'), (u'Error', u'Error'), (u'File', u'File'), (u'BPS', u'BPS'),)
type = models.CharField(max_length=7, choices=TYPE_CHOICES)
job = models.ForeignKey(Jobs)
views.py:
WHEN_CHOICES = ( (u'', ''), (1, u'Today'), (2, u'Two days'), (3, u'Three Days'), (7, u'Week'),(31, u'Month'),)
class MessageSearch(ModelForm): #Class that makes a form from a model that can be customized by placing info above the class Meta
message = forms.CharField(max_length=25, required=False)
job = forms.CharField(max_length=25, required=False)
happened = forms.CharField(max_length=14, widget=forms.Select(choices=WHEN_CHOICES), required=False)
class Meta:
model = Message
That's the code I have now. As you can see it makes a form based on a model. I redefined message in the form because I'm using an icontains filter so I didn't need a giant text box. I redefined the date mostly because I didn't want to have to mess around with dates (I hate working with dates! Who doesnt?) And I changed the jobs field because otherwise I was getting a drop down list of existing jobs and I really wanted to be able to search by common words. So I was able to mark all of those as not required
The problem is it's marking all my other fields as required because in the model they're not allowed to be blank.
Now in the model they can't be blank. If they're blank then the data is bad and I don't want it in the DB. However the form is only a filter form on a page to display the data. I'm never going to save from that form so I don't care if fields are blank or not. So is there an easy way to make all fields as required=false while still using the class Meta: model = Message format in the form? It's really handy that I can make a form directly from a model.
Also this is my first serious attempt at a django app so if something is absurdly wrong please be kind :)
You can create a custom ModelForm that suit your needs. This custom ModelForm will override the save method and set all fields to be non-required:
from django.forms import ModelForm
class SearchForm(ModelForm):
def __init__(self, *args, **kwargs):
super(SearchForm, self).__init__(*args, **kwargs)
for key, field in self.fields.iteritems():
self.fields[key].required = False
So you could declare your forms by simply calling instead of the ModelForm, e.g.:
class MessageForm(SearchForm):
class Meta:
model = Message
You could also pass empty_permitted=True when you instantiate the form, e.g.,
form = MessageSearch(empty_permitted=True)
that way you can still have normal validation rules for when someone does enter data into the form.
I would give a try to the django-filter module :
http://django-filter.readthedocs.io/en/develop/
fields are not required. these are filters actually. It would look like this :
import django_filters
class MessageSearch(django_filters.FilterSet):
class Meta:
model = Message
fields = ['happened', 'filename', 'message', '...', ]
# django-filter has its own default widgets corresponding to the field
# type of the model, but you can tweak and subclass in a django way :
happened = django_filters.DateFromToRangeFilter()
mandatory, hidden filters can be defined if you want to narrow a list of model depending on something like user rights etc.
also : setup a filter on a 'reverse' relationship (the foreignkey is not in the filtered model : the model is referenced elsewhere in another table), is easy, just name the table where the foreign key of the filtered model field is :
# the 'tags' model has a fk like message = models.ForeignKey(Message...)
tags= django_filters.<some filter>(name='tags')
quick extendable and clean to setup.
please note I didn't wrote this module, I'm just very happy with it :)