0

我陷入了这个问题:

我有两个模型:

位置和价格。

每个位置都有它的费率,可能有多个费率。

我想按其费率升序排列位置。

显然,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
4

4 回答 4

1

好吧,问题不在于如何在 Django 中查询您描述的问题。这是您的问题要么不正确,要么没有经过深思熟虑。让我用一个例子来解释:

假设您有两个Location对象,l1并且l2l1有两个Rate与之相关的对象r1r3,这样r1.rate = 1r3.rate = 3; 并且l2有一个与之相关的速率对象,r2,这样r2.rate = 2。现在查询结果的l1顺序应该是什么?由于' 的比率小于' 的比率,而另一个大于' 的比率。l2l2l1l1l2l2

于 2013-08-10T09:47:00.293 回答
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')
于 2013-08-10T08:05:00.240 回答
1

可能你想要这样的东西:

locations = (Location.objects.filter(**s_kwargs)
             .values('locations_rate__rate')
             .annotate(Count('locations_rate__rate'))
             .order_by('locations_rate__rate'))

您需要 ,Count()因为您实际上需要一个GROUP BY查询,并且仅适用于诸如or之GROUP BY类的聚合函数。COUNTSUM

无论如何,我认为您的问题可以正常解决distinct()

locations = (Location.objects.filter(**s_kwargs)
             .order_by('locations_rate__rate')
             .distinct('locations_rate__rate'))

为什么要annotate()改用?

我还没有测试过两者,但希望它有所帮助。

于 2013-08-10T14:47:31.837 回答
1

annotate(*args, **kwargs),使用提供的聚合值列表(平均值、总和等)注释 QuerySet 中的每个对象,这些聚合值是在与 QuerySet 中的对象相关的对象上计算的。

因此,如果您只想获取按其费率排序的位置,则不必使用 annotate()

     you can try this :

     loc = Location.objects.all()
     rate = Rate.objects.filter(loc=rate__location).order_by('-rate')
于 2013-08-10T09:04:09.213 回答