Django: efficient filtering in the ORM across ForeignKeys?

北城余情 提交于 2020-01-06 01:46:27

问题


I'm trying to construct a moderately complex filter in the Django ORM, and I'm not sure if I could do it more efficiently.

My app lets users search for shoes in a particular size. So if they select a size (or multiple sizes), I look for all the shoes available in that size.

This is my model structure. There's an object for each shoe (Shoe), an object for each size (ShoeSize) (standardised across manufacturers), and an object (ShoeSizeAvailable) that only gets created if a particular shoe is available in a particular size.

class Shoe(ClothingItem):
  price = models.FloatField(null=True,blank=True,db_index=True) ... 

class ShoeSize(models.Model):
  code = models.CharField(max_length=8) ...

class ShoeSizeAvailable(models.Model):
  shoe = models.ForeignKey(Shoe)
  size = models.ForeignKey(ShoeSize)

And this is how I currently do the filtering:

kwargs = {}
args = ()
if query['price_from']: 
  kwargs['price__gte'] = float(query['price_from'][0])
# Lots of other filters here... 
results = Shoe.objects.filter(*args, **kwargs)

if query['size']: 
    # The query is a list like [6, 6.5]
    # Get all potential ShoeSizeAvailable matches. 
    sizes = ShoeSizeAvailable.objects.filter(size__code__in=query['size'])
    # Get only the ones that apply to the current shoe. 
    shoe_ids = sizes.values_list('shoe', flat=True)
    # Filter the existing shoe results for these values.  
    results = results.filter(id__in=shoe_ids)

Is this the most efficient way? I'm concerned that __in queries might be inefficient with long lists like these.


回答1:


I would do this this way:

if query['size']:
    results = results.filter(shoesizeavailable__size__code__in=query['size'])


来源:https://stackoverflow.com/questions/17660010/django-efficient-filtering-in-the-orm-across-foreignkeys

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!