Django performance with `not in` filter with giant list?

牧云@^-^@ 提交于 2019-12-12 04:58:13

问题


I am currently making a school project where I am building a website that lets you rate nearby restaurants (1-5 stars). The only caveat is that I will show users the restaurants based on location (e.g. closest ones first) and that once they have rated a restaurant, it will never be shown to them again.

Currently I have something like this in mind

class User(models.Model):
    username = models.CharField(primary_key=True, max_length=20)
    location = models.SomeGeoPointField
    ...

class Restaurant(models.Model):
    title = models.CharField(primary_key=True, max_length=20)
    location = models.SomeGeoPointField
    ...

class Rating(models.Model):
    for    = models.ForeignKey(User, on_delete=models.CASCADE)
    from   = models.ForeignKey(Restaurant, on_delete=models.CASCADE)
    rating = models.IntegerField()

I am having trouble thinking how the query would look like, and if I used a not in to filter out existing ratings, about the possible performance hit


回答1:


The query you need is one that excludes the restaurants which the user has already rated. Django will create an efficient query if you do this:

Restaurant.objects.exclude(rating__user=request.user)

You can make the queries even easier if you recognise that what you have here is a many-to-many relationship between User and Restaurant, with a through table of Rating. So:

class User(models.Model):
    ...
    ratings = models.ManyToManyField('Restaurant', through='Rating', related_name='users_rating')

This doesn't actually alter this query very much - now it is:

Restaurant.objects.exclude(users_rating=request.user)

but it will certainly make other queries easier.



来源:https://stackoverflow.com/questions/43872910/django-performance-with-not-in-filter-with-giant-list

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