【问题标题】:Django performance with `not in` filter with giant list?带有巨大列表的“不在”过滤器中的 Django 性能?
【发布时间】:2017-10-07 22:44:09
【问题描述】:

我目前正在做一个学校项目,我正在建立一个网站,让您对附近的餐馆(1-5 星)进行评分。唯一需要注意的是,我将根据位置向用户显示餐厅(例如,首先显示最近的餐厅),并且一旦他们对餐厅进行了评分,就再也不会向他们显示。

目前我有这样的想法

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()

我无法思考查询的外观,如果我使用not in 过滤掉现有评级,可能会对性能造成影响

【问题讨论】:

  • 餐厅模型中还需要用户的外键,以便查看位置
  • @Exprator 想写一个更详细的例子吗?

标签: mysql django django-models django-orm


【解决方案1】:

您需要的查询是排除用户已经评分的餐馆的查询。如果你这样做,Django 将创建一个高效的查询:

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

如果您认识到您在此处拥有的是用户和餐厅之间的多对多关系以及评级的直通表,那么您可以使查询更加容易。所以:

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

这实际上并没有太大地改变这个查询 - 现在它是:

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

但它肯定会使其他查询更容易。

【讨论】:

  • 感谢您的帮助!
  • 您好,我还有一个非常相似的问题(如果我介绍了一个中介Profile 模型会发生什么)如果您能抽出时间再次提供帮助,我将非常感激 - stackoverflow.com/questions/45134299/…
猜你喜欢
  • 2020-03-26
  • 2014-03-21
  • 2015-02-26
  • 1970-01-01
  • 2021-08-16
  • 2014-03-31
  • 2018-05-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多