django评论框架:distinct()不起作用?

时间:2012-01-26 11:47:59

标签: django distinct django-comments

在评论模型的任何字段上运行distinct()始终返回所有记录

  

Comment.objects.values( '用户')。不同的()

     

[{'user':1},{'user':0},{'user':0},{'user':0},{'user':0},   {'user':1},{'user':1},{'user':1},{'user':1}]

     

Comment.objects.values( 'IP_ADDRESS')。不同的()

     

[{'ip_address':u'127.0.0.1'},{'ip_address':u'192.168.0.180'},   {'ip_address':u'192.168.0.180'},{'ip_address':u'192.168.0.180'},   {'ip_address':u'192.168.0。 180'},{'ip_address':u'192.168.0.180'},   {'ip_address':u'192.168.0.180'},{'ip_address':u'192.168.0.180'},   {'ip_address':u'192.168.0.180'}]

为什么会这样?有没有解决的办法?谢谢!

ps:distinct()在我的测试期间在自定义模型的不同类型的字段中运行得非常好。关于评论框架的一些特别之处?

结论 谢谢大家回答这个问题,再加上一些阅读,我得出如下结论:

  1. values()会影响final的SELECT部分​​中的查找字段 SQL( “values() takes optional positional arguments, *fields, which specify field names to which the SELECT should be limited”)
  2. order_by()也将其参数添加到SELECT部分​​。
  3. 在查找中使用distinct()将导致sql看起来像这样:

      

    SELECT DISTINCT [fields1,fields2,fields3] FROM ... WHERE ...

    和字段的值一起决定记录是否唯一。这些字段可能来自查找中的values()或order_by()函数。

  4. So the order_by() is adding some unwanted effects when combined with distinct(), the fields specified in order_by is also take into consideration whether a record is unique

  5. Django Comment默认有一个隐藏的order_by参数,从而产生了整个问题。当返回qs时,任何模型都有一个隐藏的order_by会导致同样的问题。

  6. 解决问题的方法是在末尾添加一个空的order_by() lookup,删除默认的order_by。

3 个答案:

答案 0 :(得分:8)

Comment.objects.values('user').distinct().order_by()

答案 1 :(得分:3)

我尚未确认这是原因,但Comment模型的默认排序会影响distinct()方法:

In [1]: print Comment.objects.values('ip_address').distinct().query
SELECT DISTINCT "django_comments"."ip_address", "django_comments"."submit_date" FROM "django_comments" ORDER BY "django_comments"."submit_date" ASC

这是documented feature

现在,两条评论的时间戳如何相同?我想你使用的MySQL不支持任何不到一秒的时间。

如果您想摆脱默认排序,请执行以下操作:

Comment.objects.order_by().values('ip_address').distinct()

答案 2 :(得分:1)

您可以将查询包装在集合中;

distinct() 与 values() 不兼容,根据 documentation

ip_sets = set(Comment.objects.order_by().values('ip_address'))
ip_list = list(set(Comment.objects.order_by().values('ip_address')))