Django在另一个不存在的表中按键排序

时间:2012-10-10 02:48:47

标签: python mysql django

使用Django,我有2个模型。

Model1 -> User
          -> ID
          -> Some properties

Model2 -> Activeness
          -> UserId (Foreign Key to User)
          ->rating

这是一个简化的案例。 我试图在活动表中获得按其评级排序的用户列表。 User.objects.all()。ORDER_BY( 'activeness__rating')

这没关系。

但是,我有一些情况尚未创建新用户的活动对象。 这将导致那些新用户出现在所获得的列表的顶部。 我希望它们出现在列表的底部。

我不能在python中求助,因为我一次使用分页并检索1页。

任何人都可以提供建议。 谢谢。

2 个答案:

答案 0 :(得分:1)

您是否尝试过使用annotate?这可能会有所帮助

使用注释,你可以做这样的事情

User.objects.all().annotate(num_rating=Count('activeness__rating')).order_by('num_rating')

我希望它有所帮助

答案 1 :(得分:1)

TLDR:过滤掉activeness为空的用户对象,稍后再添加。

长版:给出一些像

这样的模型
class MyUser(models.Model):
    activeness = models.ForeignKey('Activeness', null=True)
    name = models.CharField(max_length=50)

    def __unicode__(self):
        return "{}: {}".format(self.name, self.activeness.rating if self.activeness else "no rating")

class Activeness(models.Model):
    rating = models.FloatField()

和一些像这样的样本数据

<MyUser: Bob: 3.62810036125>,
<MyUser: Tim: no rating>,
<MyUser: Jim: 2.41014167534>,
<MyUser: Rod: 1.35651839383>]

您可以排除没有以下评分的用户:

>>> MyUser.objects.filter(activeness__rating__isnull=False).order_by('activeness__rating')
[<MyUser: Rod: 1.35651839383>, <MyUser: Jim: 2.41014167534>, <MyUser: Bob: 3.62810036125>]

然后将它们追加到最后,使用chain() from itertools可以提高效率:

>>> from itertools import chain
>>> chain(MyUser.objects.filter(activeness__rating__isnull=False).order_by('activeness__rating'), MyUser.objects.filter(activeness__rating__isnull=True))
[<MyUser: Rod: 1.35651839383>,
 <MyUser: Jim: 2.41014167534>,
 <MyUser: Bob: 3.62810036125>,
 <MyUser: Tim: no rating>]

例如,如果我们有调试,我们可以看到这可以防止对查询集进行毫无意义的评估。

>>> from django.db import connection
>>> import pprint
>>> connection.queries = []
>>> for u in chain(MyUser.objects.filter(activeness__rating__isnull=False).order_by('activeness__rating').select_related('activeness'), MyUser.objects.filter(activeness__rating__isnull=True)):
>>>     print "At {u} we've done {count} SQL queries".format(u=u, count=len(connection.queries))
At Rod: 1.35651839383 we've done 1 SQL queries
At Jim: 2.41014167534 we've done 1 SQL queries
At Bob: 3.62810036125 we've done 1 SQL queries
At Tim: no rating we've done 2 SQL queries

当然,你仍然需要做一些工作才能让它与Django paginator一起使用,但这超出了这个问题的范围。