Django Reverse Lookup of Foreign Keys

Django reverse lookup of foreign keys

You can use events = venue.event_set to go the other way.

Note that venue.event_set is a manager object, like Event.objects, so you can call .all, .filter, .exclude and similar on it to get a queryset.

See the Django documentation

How to reverse lookup the foreign key in Django

You can filter with a Q object [Django-doc]:

from django.db.models import Q
Vendor.objects.filter(
Q(vendor_name__icontains=keyword) | Q(food__food_title__icontains=keyword)
)

Django update a Foreign Key model using reverse lookup

You need to go through the Products table. Have you tried:

 Products.objects.filter(shelfproduct__shelf_name='Shelf A', shelfproduct__kioskshelf__kiosk_name='kiosk1').update(quantity=<quantity>)

django reverse lookup foreignkey not working

You have specified related_name in your foreign key loopkup. so rating_set should not work now.

You can lookup like

ratings_of_video = vid_rate.video.all()

A better naming convention will be to use ratings in your related_name

class Rating(models.Model):
video = models.ForeignKey('Video', related_name='ratings', null=True)

and then query like

ratings_of_video = vid_rate.ratings.all()

Reverse foreign key in filter of QuerySet in Django

You can obtain the queryset of Humans that own (at least) one Jacket with:

Human.objects.filter(jacket__isnull=False).distinct()

This works because we make a LEFT OUTER JOIN on the Jacket model, and we filter out the ones without a related Jacket with jacket__isnull=False. By using .distinct() we prevent that the same Human is returned multiple times (once per related Jacket).

In the query it uses the related_name_query to reference the related object, which is by default the name of the model in lowercase. In case a related_name is specified, it will use the related_name.

Reverse lookup of foreign key in python django

return Dept.objects.filter(employees_set__name='XYZ')

Should do the job.

complexity of a reverse django foreign key lookup

But I would like to know about the second one. Does it search through all the Picture table in the database to find all the pictures that have post=p or is the information available when I get p in the first query?

Short answer: by default a ForeignKey adds an index, making retrievals quite fast (logarithmic in the number of values, and linear in the number of reverse records).

That depends on whether the database constructs an index on the ForeignKey. By default Django will construct an index. This means that it does not only stores the rows of the table, but also a datastructure that allows fast lookup of all the rows that have a specific value.

The implementation of the index can be database dependent. In MySQL it will by default use a BTREE, this means that for the lookup of a value, it takes approximately O(log n) to obtain the collection, and O(k) with k the number of items with that foreign key to retrieve all. But other index structures exist, like some sort of hashtable, that even allow (slightly) faster lookup, although a hashtable for example will not be that efficient to retrieve all elements with a ForeignKey less than a given number.

You can also add an index on other columns, for example:

class Post(models.Model):
name = models.CharField(max_length=25, db_index=True, unique=True)

So now retrieving all Post objects with a name a given name, will run faster as well.

Using indices is of course not "free": it means that each time you insert or remove a record, the index need to be altered as well (typically this also requires O(log n)). If you update a record by changing the value of the foreign key, then that index needs to be altered as well. So indices provide a significant speedup, but one should aim to only put indexes on column on which one performs a lookup frequently, since otherwise the cost of "maintaining" the index can be larger than the gain of speeding up the lookup process.

django query annotate values get list from reverse foreign key

If you are using a postgres as a database, then you can use an ArrayAgg function:

from django.contrib.postgres.aggregates import ArrayAgg

authors = Author.objects.annotate(blogs=ArrayAgg('blog_set__title'))


Related Topics



Leave a reply



Submit