I have a model with a field that is a list.
For example:
mymodel.sessions = [session1, session2]
I need a query to get all mymodels that session1 is exist their sessions.
The model`s field looks like that
sessions = models.ForeignKey("Session", related_name="abstracts",
null=True, blank=True)
Thank you !
You can use reverse lookups that go back along the foreign key to query for values in the related model.
MyModel.objects.filter(sessions__id=1)
That will filter all MyModels that have a foreign key to a session with an id of 1.
For more information see https://docs.djangoproject.com/en/1.10/topics/db/queries/#lookups-that-span-relationships
From the Django docs for filter:
filter(**kwargs)
Returns a new QuerySet containing objects that match the given lookup parameters.
You can filter on a ForeignKey relationship using the id, if you have it:
The field specified in a lookup has to be the name of a model field. There’s one exception though, in case of a ForeignKey you can specify the field name suffixed with _id. In this case, the value parameter is expected to contain the raw value of the foreign model’s primary key.
In your instance, this would like the following:
mymodel.objects.filter(sessions_id=4)
If you want to filter on any other field in the Sessions model, simply use a double underscore with the field. Some examples:
mymodel.objects.filter(sessions__name='session1')
mymodel.objects.filter(sessions__name__contains='1')
Related
Two tables: post and rating.
rating contains column - post (FK) that is post table's primary ID.
I'm trying to filter table rating by columns user and ratingtype to get post (FK) value that I could use to filter post table by.
Post.objects.filter(pk__in=Rating.objects.get(post=post).filter(Rating.objects.filter(user = self.request.user, ratingtype='like')))
You can look "through" relations with two consecutive underscores (__), so:
Post.objects.filter(
rating__user=self.request.user,
rating__ratingtype='like'
).distinct()
The .distinct() [Django-doc] clause prevents returing the same Post multiple times if the user has given multiple ratings.
If you specified a related_query_name=… [Django-doc] or related_name=… [Django-doc] in the ForeignKey, then that is the name of the relation in reverse, so then instead of rating__ it is related_query_name__ (with related_query_name the value you used for the related_query_name=… parameter).
I'm looking to extract the '35' and '34' values from this object:
[<FriendshipRequest: 35>, <FriendshipRequest: 34>]
These are primary keys which i would like to use as parameters to get information about the specific user the primary key relates to but I am unsure on how to separate the values from the rest of the object attributes to substitute into User.objects.get(pk=pk) as at the moment pk=<FriendshipRequest: 35> whereas i'd like pk=35.
I am just wondering if anyone has any ideas on how to approach this problem?
Cheers
What's the name of the user field on the FriendshipRequest model?
So the problem is that pk is the primary key of FriendshipRequest in this example and you need the foreign key of the user...
So for example if you are looking for the user who is the sender(Under the assumption that this fields name is sender inside the FriendshipRequest model), you would access it by friendship_request.sender or if you just want the primary key of the user friendship_request.sender.pk
Why you can't just use User.objects.get(pk=FriendshipRequestObj.id). I am assuming id as your pk in model.
I have a table called user_info. I want to get names of all the users. So the table has a field called name. So in sql I do something like
SELECT distinct(name) from user_info
But I am not able to figure out how to do the same in django. Usually if I already have certain value known, then I can do something like below.
user_info.objects.filter(name='Alex')
And then get the information for that particular user.
But in this case for the given table, I want to get all the name values using django ORM just like I do in sql.
Here is my django model
class user_info(models.Model):
name = models.CharField(max_length=255)
priority = models.CharField(max_length=1)
org = models.CharField(max_length=20)
How can I do this in django?
You can use values_list.
user_info.objects.values_list('name', flat=True).distinct()
Note, in Python classes are usually defined in InitialCaps: your model should be UserInfo.
You can use values_list() as given in Daniel's answer, which will provide you your data in a list containing the values in the field. Or you can also use, values() like this:
user_info.object.values('name')
which will return you a queryset containing a dictionary. values_list() and values() are used to select the columns in a table.
Adding on to the accepted answer, if the field is a foreign key the id values(numerical) are returned in the queryset. Hence if you are expecting other kinds of values defined in the model of which the foreign key is part then you have to modify the query like this:
`Post.objects.values_list('author__username')`
Post is a model class having author as a foreign key field which in turn has its username field:
Here, "author" field was appended with double undersocre followed by the field "name", otherwise primary key of the model will be returned in queryset. I assume this was #Carlo's doubt in accepted answer.
We have a limitation for order_by/distinct fields.
From the docs: "fields in order_by() must start with the fields in distinct(), in the same order"
Now here is the use case:
class Course(models.Model):
is_vip = models.BooleanField()
...
class CourseEvent(models.Model):
date = models.DateTimeField()
course = models.ForeignKey(Course)
The goal is to fetch the courses, ordered by nearest date but vip goes first.
The solution could look like this:
CourseEvent.objects.order_by('-course__is_vip', '-date',).distinct('course_id',).values_list('course')
But it causes an error since the limitation.
Yeah I understand why ordering is necessary when using distinct - we get the first row for each value of course_id so if we don't specify an order we would get some arbitrary row.
But what's the purpose of limiting order to the same field that we have distinct on?
If I change order_by to something like ('course_id', '-course__is_vip', 'date',) it would give me one row for course but the order of courses will have nothing in common with the goal.
Is there any way to bypass this limitation besides walking through the entire queryset and filtering it in a loop?
You can use a nested query using id__in. In the inner query you single out the distinct events and in the outer query you custom-order them:
CourseEvent.objects.filter(
id__in=CourseEvent.objects\
.order_by('course_id', '-date').distinct('course_id')
).order_by('-course__is_vip', '-date')
From the docs on distinct(*fields):
When you specify field names, you must provide an order_by() in the QuerySet, and the fields in order_by() must start with the fields in distinct(), in the same order.
I'm using Django (I'm new to it). I want to define a foreign key, and I'm not sure how to go about it.
I have a table called stat_types:
class StatTypes(models.Model):
stat_type = models.CharField(max_length=20)
Now I want to define a foreign key in the overall_stats table to the stat_type id that is automatically generated by django. Would that be the following?
stat_types_id = models.ForeignKey('beta.StatTypes')
What if I wanted instead to have the stat_type column of the stat_types table be the foreign key. Would that be:
stat_type = models.ForeignKey('beta.StatTypes')
I guess my confusion arises in not knowing what to name the column in the second model, in order for it to know which column of the first model to use as the foreign key.
Thanks!
it does not matter what name you give to FK column name. Django figures it out that it is a ForeignKey and appends _id to the field. So you do not need _id here. I think this is good enough
stat_type = models.ForeignKey('beta.StatTypes')
Doc says:
It’s suggested, but not required, that the name of a ForeignKey field
(manufacturer in the example above) be the name of the model,
lowercase. You can, of course, call the field whatever you want.