Django-在yelp之类的应用中过滤掉已经评级的餐厅 [英] Django - filtering out already rated restaurants in yelp like app
本文介绍了Django-在yelp之类的应用中过滤掉已经评级的餐厅的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
请考虑以下数据库模型:
Consider the following database model:
class User:
id = models.BigAutoField(primary_key=True)
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
class Restaurant:
id = models.BigAutoField(primary_key=True)
title = models.CharField(max_length=50)
class Rating:
id = models.BigAutoField(primary_key=True)
by_user = models.ForeignKey(to='User',
on_delete=models.PROTECT,
related_name='written_ratings')
for_restaurant = models.ForeignKey(to='Restaurant',
on_delete=models.PROTECT,
related_name='received_ratings')
score = models.SmallIntegerField()
# make sure only one vote per user per restaurant
class Meta:
unique_together = ('by_user', 'for_restaurant')
对于给定的用户
,通过执行以下查询,我们可以获得尚未评级的餐馆
的列表(我从我的最新帖子中学到的东西)
For a given User
, we can obtain a list of Restaurant
that we have not yet rated by performing the following query (that I have learned from my last post)
eligible_restaurants = Restaurant.objects.exclude(rating__by_user_id=my_id)
但是,当评分
不直接指向餐馆$时会发生什么c $ c>-而是位于中间的
个人资料
对象上?
But what happens when the Ratings
don't point directly at the Restaurants
- but rather at an intermediate Profile
object?
class User:
id = models.BigAutoField(primary_key=True)
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
class Restaurant:
id = models.BigAutoField(primary_key=True)
title = models.CharField(max_length=50)
current_profile = models.OneToOneField(to='Profile',
on_delete=models.PROTECT,
related_name='+')
# the `+` means to not generate a related name
class Profile:
# this is here acting as an intermediate between
# `Restaurant` and `Rating` so that we can keep track
# of all reviews - deleting/remaking would simply be
# creating a new `Profile` and setting the `Restaurant`
# to point to it instead - the old one will act as a
# historical record
id = models.BigAutoField(primary_key=True)
by_restaurant = models.ForeignKey(to='Restaurant',
on_delete=models.PROTECT,
related_name='written_profiles')
picture_url = models.CharField(max_length=500)
picture_desc = models.CharField(max_length=500)
class Rating:
id = models.BigAutoField(primary_key=True)
by_user = models.ForeignKey(to='User',
on_delete=models.PROTECT,
related_name='written_ratings')
for_profile = models.ForeignKey(to='Profile',
on_delete=models.PROTECT,
related_name='received_ratings')
score = models.SmallIntegerField()
# make sure only one vote per user per restaurant
class Meta:
unique_together = ('by_user', 'for_profile')
如何查询
推荐答案
您可以从餐馆开始过滤它们
You could filter them starting with restaurants
restaurant_ids = Rating.objects.filter(by_user=user).values_list('for_profile__by_restaurant', flat=True).distinct()
eligible_restaurants = Restaurant.objects.exclude(id__in=restaurant_ids)
注意:由于django的查询集是惰性的,因此只会生成一个查询。
Note: this will generate only one query because django's querysets are lazy.
这篇关于Django-在yelp之类的应用中过滤掉已经评级的餐厅的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文