[Fixed]-How can I filter a Django-Model with 2 foreign keys?

1👍

Without spelling out a complete picture, it seems you’re using a complicated scheme. Using the related_name keyword argument for a model’s field definition allows you to find all reverse-related foreign key objects; this can be set per foreign key and called by a parent model.

class OrderItem(models.Model):
    order = models.ForeignKey(Order)
    picture = models.ForeignKey(Picture,related_name='order_items')
    amount = models.PositiveSmallIntegerField()

for pic in Picture.objects.all():
    print(pic.order_items.all())

>>> [queryset of all order_items related to first Picture instance in Picture.objects.all()]
>>> [queryset of all order_items related to second Picture instance... etc.]

0👍

The previous answer is not correct. You will kill your database that way. If you would need more info than just count, then you should use prefetch_related, otherwise when looping it will hit database in every iteration.

If you need multiple orders for multiple events, then there is many-to-many relationship https://docs.djangoproject.com/en/dev/topics/db/examples/many_to_many/

Since you just need count Orders for Event, it’s even easier.
Let’s name each foreign key in the way with unique related_name:

class Picture(models.Model):
    event = models.ForeignKey(Event, related_name='event_pictures')

class OrderItem(models.Model):
    order = models.ForeignKey(Order, related_name='ordered_items')
    picture = models.ForeignKey(Picture, related_name='picture_orders')

Now, It’s a bit hard for me to navigate in the database on the spot, but you should be able to do something like:

Events.objects.annotate(Count('event_pictures__picture_orders__order'))

Maybe a modify will be needed or adding a distinct. However you should definitely use this approach and not any iteration in python. That would completely kill the app. However if you would absolutely need to, then definitely use prefetch_related('event_pictures__picture_orders__order'), as mentioned earlier.

Leave a comment