I have 2 models, "Listing" and "Watchlist". Watchlist has a primary key that is referencing Listing.
For every "Watchlist" object (that has the same user X) I want to get the according "Listing" entry in form of a QuerySet.
I really struggle with this, because I don't know how to incorporate a for-loop into a queryset request.
class Watchlist(models.Model):
listing = models.ForeignKey(Listing, on_delete=models.CASCADE, related_name="watchlists")
user = models.ForeignKey(User, on_delete=models.CASCADE)
Since listing field has related_name="watchlists", we can filter using related_name like this:
Listing.objects.filter(watchlists__user = X) # X is a user instance.
Note that __ is used for field lookups. __user is for user field lookup.
If listing field does not have any related name, we can filter using model name (Watchlist) with _set to the referencing model.
Listing.objects.filter(Watchlist_set__user = X) # X is a user instance.
Related
There is 2 models Registration and RegistrationCompletedByUser, I want Registration queryset from RegistrationCompletedByUser with filters(user=request.user, registration__in=some_value, is_completed=True) over RegistrationCompletedByUser. Hence result should be like <QuerySet [<Registration: No name>, <Registration: p2>, <Registration: p-1>]>.
Now what I tried is
Registration.objects.prefetch_related('registrationcompletedbyuser_set') but filters() not working. Another way I tried is model Managers but don't pass parameters for custom filtering.
models.py
class Registration(models.Model):
name=models.CharField(max_length=255)
number=models.SmallIntegerField(null=True, blank=True)
class RegistrationCompletedByUser(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
registration= models.ForeignKey(Registration, on_delete=models.CASCADE)
points = models.SmallIntegerField(default=100)
is_completed = models.BooleanField(default=False)
If I understood this properly, you want to get all Registrations that related to a query instead of a single object.
qs_1 = RegistrationCompletedByUser.objects.filter(user=request.user, is_completed=True).values_list("registration__id", flat=True)
qs_2 = Registration.objects.filter(id__in=qs_1)
As I understood your question is related to django. So actually there is common way to get related query set from another. When you specify ForeignKey to another model actually django automatically creates 'Related Model' + '_set' relation.
I actually didn't get from you question what you are intended to do. In your situation there are many RegistrationCompletedByUser related to one Registration. So what you can do it's to receive all RegistrationCompletedByUser instances from Registration instance by related name for ForeignKey registration of RegistrationCompletedByUser which in your case registration_set. Actually better to specify in RegistrationCompletedByUser model related name as attribute like this:
models.ForeignKey(Registration, on_delete=models.CASCADE,
related_name='registrations')
And after this let's say you have instance of Registration reg1. So to receive queryset of RegistrationCompletedByUser:
reg1.registrations.all()
And you can use filter on it with attributes from Registration model.
And if you want to receive Registration from RegistrationCompletedByUser, again in your case it's just one Registration to many RegistrationCompletedByUser, so let's say we have reg_completed_1, to receive it's only one registration:
reg = reg_completed_1.registration
I have used two models and a django built in User model.
class UserInfo(models.Model):
user = models.OneToOneField(User)
user_contact = models.CharField()
age = models.IntegerField()
class Review(models.Model):
user = models.ForeignKey('exam.UserInfo')
is_reviewed= models.BooleanField()
The UserInfo field is one to one with the User model. User model have the 'username' field that I want to retrieve. But I can't get through how to get the username of those users who have is_reviewed field is 0. So far what I was trying but failed to retrieve:
result=Review.objects.select_related('user_id__id').filter(is_reviewed=0)
You don't necessarily need select_related, that's a performance tuning tool. If you want Review model instances, just make your query and retrieve related values from that as normal:
result = Review.objects.filter(is_reviewed=False)
Then the name is available with dotted lookups, eg:
result[0].user.user.username
These will make further queries - select_related helps you tune whether or not to prefetch those.
If you just want the usernames, you can use a values or values_list query, eg:
usernames = Review.objects.filter(is_reviewed=False).values_list('user__user__username', flat=True)
I'm extending Django's (v1.9) built-in User model with Player class, to add some extra properties.
class Player(models.Model):
TIMEZONES=()
user = models.OneToOneField(User, on_delete=models.CASCADE)
... (player-specific properties here)
time_zone = models.CharField(max_length=255, choices=PRETTY_TIMEZONE_CHOICES, blank=True, null=True,)
When creating users from Django admin panel, I don't always need to create players, so sometimes only User gets created. As a result, Player and User IDs don't exactly match. Turns out that this leads to a problem when populating ModelForms of models that are linked to Player, like this one:
class City(models.Model):
player = models.ForeignKey(Player, on_delete=models.CASCADE)
name = models.CharField(max_length = 100)
x_coord = models.SmallIntegerField()
y_coord = models.SmallIntegerField()
region = models.CharField(max_length = 100)
def __unicode__(self):
return str(self.player) + "-" + str(self.name)
class Meta:
db_table = 'cities'
class CityForm(ModelForm):
class Meta:
model = City
fields = (
'name',
'player',
'x_coord',
'y_coord',
'region')
This modelForm is used when creating a new city. When User ID and Player ID match, there is no problem, player ID gets populated in the form and city is successfully created. When User ID and Player ID are different, player ID is not populated in the form, the form fails to validate, and city creation fails.
I have no problem getting Player ID from request.user, and I could fix up the player ID before validating after getting POST data. I've also added a post-save hook so that Player always gets created, so the IDs will always match. But it seems that form should be populated with player ID in the first place, since user data is accessible and it's a one to one relationship.
What am I missing here?
What you are missing is that when you instantiate a ModelForm to create a new row that's related to some existing object, Django has no way of knowing the id of the related object. You need to tell it somehow.
One way to do that is, when you are displaying the form in response to a GET, use the initial argument to the form constructor:
myform = MyModelFormClass(None, initial={ 'myfkfield': myrelatedobject.pk })
Now the form class knows what value to pre-fill in when it renders the form, and when the form is posted, that field will be posted with it.
The other way to do it would be to omit the relation field from your form altogether, then fill it in later before you save, by using the commit argument to the form save method:
myform = MyModelFormClass(request.POST)
# this causes form values to be filled into the instance without actually
# writing to the database yet.
myinstance = myform.save(commit=False)
myinstance.myfkfield = myrelatedobject
# now really write to database
myinstance.save()
Note that this would be for an insert. For updates, you need to supply the existing object to your modelform constructor, like this:
myinstance = MyModel.objects.get(pk=self.kwargs.pk)
myform = MyModelFormClass(request.POST, instance=myinstance)
Without the instance, ModelForm doesn't know what row it's updating in the database. You would think that this is all present in the HTML so it shouldn't be necessary.. but that's not how Django works. You need to fetch the object existing from the database, and pass it to the ModelForm constructor along with the request.POST data. Then when you call myform.save() it will validate the form, merge its data with the existing object, and save the object. Using commit=False results in the last of those three steps being deferred, so that you can make any adjustments or checks to the updated instance before it is actually saved.
I have a model which is an extension of a User model in Django 1.8. I am also connecting to a MySQL database for this.
class LibraryUser(models.Model):
user_id = models.OneToOneField(User)
is_catalogue_subscriber = models.BooleanField(default=True)
is_research_subscriber = models.BooleanField(default=True)
library_membership_number = models.CharField(max_length=64)
The reason why I extended the User model, of course is to use the authentication framework.
So now, I want to create a new LibraryUser using the library_membership_number as the login username. How should I do so? Do I create the User first then reference the LibraryUser?
ie given some_ variables either received by a POST or by migration of users to the new table
u = User.objects.create_user(email=some_email, password=some_password)
lu = LibraryUser(library_membership_number, user_id = u.id)
lu.save()
Or is there a correct way to do this? Tried finding online but can't find something to particularly address this problem.
You should assign value to the specify fields as the following:
lu = LibraryUser(library_membership_number= '...', user_id = user)
lu.save()
library_membership_number
You can't just assign a variable to library_membership_number. model is a object containing the fields. You should appoint the field and assign it: library_membership_number= '...', or model can't parse which field you will store.
user_id
It has defined foreignkey in advance. It can accept another model object to store: user_id = user. Don't call attribute of the user to store in LibraryUser.
I am using Django Rest Framework to provide API to a mobile app. I have two models, Order and User. Order has a foreign key relation to User.
For about 1% or so of all my order objects, the User field is null. I've been testing this behavior using cURL.
If I do a cURL without a user object, it tells me "This field is required".
If done with a wrong user object, it tells me that the object does not exist. Both of these are the intended and expected behaviors.
I'm trying to figure out how it is possible for some of the Order objects to be saved without a user field. Is there something I'm not taking into account?
My views:
class OrderList (generics.ListCreateAPIView):
model = Order
serializer_class = OrderSerializer
And serializer:
class OrderSerializer (serializers.ModelSerializer):
user = serializers.SlugRelatedField(slug_field = 'user')
partial = True
class Meta:
model = Order
Models:
class User (models.Model):
uid = models.CharField(max_length =200, unique=True)
class Order (models.Model):
uid = models.ForeignKey (User, related_name = "orders", verbose_name = "User",blank=True, null=True)
You could use two different ModelSerializer classes, one for creation, that makes sure, that an Order object can't be created without a related User and one for updating orders, that passes required=False to the related field's constructor, so that you still can save existing orders that haven't a related User.
Try adding default=None to your models.ForeignKey declaration. You could also just create an anonymous user in the users table and when the user isn't specified it could set the anonymous user instead.