我陷入了这个问题:
我有两种模式:
位置和费率。
每个位置都有其费率,可能是多种费率。
我希望按照其费率按顺序排列。
显然,order_by
和distinct()
不能一起工作:
locations = Location.objects.filter(**s_kwargs).order_by('locations_rate__rate').distinct('id')
然后我阅读了文档并来到了annotate()
。但我不确定是否必须在注释之间使用函数。
如果我这样做:
locations = Location.objects.filter(**s_kwargs).annotate(rate=Count('locations_rate__rate')).order_by('rate')
但这会计算费率和订单总和。我想获得按照这些费率的价格订购费率的地点。
我的模型定义是:
class Location(models.Model):
name = models.TextField()
adres = models.TextField()
class Rate(models.Model):
location = models.ForeignKey(Location,related_name='locations_rate')
rate = models.IntegerField(max_length=2)
price_rate = models.IntegerField(max_length=2) #<--- added now
datum = models.DateTimeField(auto_now_add=True,blank=True) #<--- added now
答案 0 :(得分:1)
试试这个:
from django.db.models import Count, Sum
# if you want to annotate by count of rates
locations = Location.objects.filter(**s_kwargs) \
.annotate(rate_count = Count('locations_rate')) \
.order_by('rate_count')
# if you want to annotate on values of rate e.g. Sum
locations = Location.objects.filter(**s_kwargs) \
.annotate(rate_count = Sum('locations_rate')) \
.order_by('rate_count')
答案 1 :(得分:1)
annotate(* args,** kwargs),使用提供的聚合值列表(平均值,总和等)来注释QuerySet中的每个对象 已经在与QuerySet中的对象相关的对象上计算。
因此,如果您只想获得按其费率排序的地点,那么您不必使用注释()
you can try this :
loc = Location.objects.all()
rate = Rate.objects.filter(loc=rate__location).order_by('-rate')
答案 2 :(得分:1)
问题不在于如何在Django中查询您描述的问题。这是你的问题不正确或没有财产思考。让我用一个例子来解释:
假设您有两个Location
个对象,l1
和l2
。 l1
有两个Rate
个与之关联的对象,r1
和r3
,r1.rate = 1
和r3.rate = 3
;并且l2
有一个与其相关的费率对象r2
,例如r2.rate = 2
。现在,您的查询结果l1
跟随l2
或l2
后跟l1
的顺序应该是多少?其中一个l1
的费率低于l2
,另一个的费率高于l2
。
答案 3 :(得分:1)
可能你想要这样的东西:
locations = (Location.objects.filter(**s_kwargs)
.values('locations_rate__rate')
.annotate(Count('locations_rate__rate'))
.order_by('locations_rate__rate'))
您需要Count()
,因为您确实需要GROUP BY
个查询,而GROUP BY
仅适用于COUNT
或SUM
等汇总功能。
无论如何,我认为您的问题可以通过正常distinct()
来解决:
locations = (Location.objects.filter(**s_kwargs)
.order_by('locations_rate__rate')
.distinct('locations_rate__rate'))
为什么要使用annotate()
?
我没有测试过两者,但希望它有所帮助。