Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
django distinct不仅返回唯一字段_Django_Django Views_Distinct - Fatal编程技术网

django distinct不仅返回唯一字段

django distinct不仅返回唯一字段,django,django-views,distinct,Django,Django Views,Distinct,我有一个包含三个字段的聊天信息模型: 发件人、收件人用户模型的ForeignKey和消息作为文本字段 我正在尝试选择与发件人或收件人字段exclude request.user的所有唯一对话。我对如何实现这一点有点困惑 我有两个问题: Message.objects.filter(Q(sender = request.user)|Q(recipient = request.user)).values('sender').distinct() 即使使用order_by,也不会返回唯一记录的列表。

我有一个包含三个字段的聊天信息模型:

发件人、收件人用户模型的ForeignKey和消息作为文本字段

我正在尝试选择与发件人或收件人字段exclude request.user的所有唯一对话。我对如何实现这一点有点困惑

我有两个问题:

Message.objects.filter(Q(sender = request.user)|Q(recipient = request.user)).values('sender').distinct()
即使使用order_by,也不会返回唯一记录的列表。我有很多完全相同的发件人:{'sender':4L},{'sender':4L}收件人也是如此

第二个问题是:

我是否需要连接发件人和收件人的两个问题集,或者有其他方法获取当前request.user的整个对话列表

upd。好的,这是表格内容:

mysql> select id, sender_id, recipient_id, body from messages_message ;
+----+-----------+--------------+-----------+
| id | sender_id | recipient_id | body      |
+----+-----------+--------------+-----------+
|  1 |         4 |            1 | Message 1 |
|  2 |         4 |            1 | Message 2 |
+----+-----------+--------------+-----------+
在这里,它是

Message.objects.filter(Q(sender = request.user)|Q(recipient = request.user)).values('sender').distinct()

[{'sender': 4L}, {'sender': 4L}]
但我只希望得到一个[{'sender':4L}]

那么,怎么了

upd2。我的模型:

class Message(models.Model):
    body = models.TextField(_("Body"))
    sender = models.ForeignKey(User, related_name='sent_messages', verbose_name=_("Sender"))
    recipient = models.ForeignKey(User, related_name='received_messages', null=True, blank=True, verbose_name=_("Recipient"))
    sent_at = models.DateTimeField(_("sent at"), null=True, blank=True)
我需要选择所有发送或接收消息的对话伙伴。当前用户的request.user。

正如Rob指出的,distinct的工作方式与您预期的不同。它查看所有字段以确定唯一性,而不仅仅是在值中指定的字段

如果您使用的是PostgreSQL,那么您可以通过将参数传递给distinct来做您想做的事情。从:

您可以传递位置参数*字段以指定 应应用DISTINCT的字段的名称。这意味着 SQL查询上的SELECT DISTINCT。区别就在这里。对于一个正常的 调用时,数据库会比较每行中的每个字段 确定哪些行是不同的。对于一个与 指定字段名时,数据库将仅比较指定的 字段名

回到找到所有谈话伙伴的最终目标,我看不到一个简单、优雅的解决方案。一种方法是使用聚合:

receivers = user.sent_messages.values('recipient')
                .aggregate(num_messages=Count('id'))
senders = user.received_messages.values('sender')
              .aggregate(num_messages=Count('id'))

如果您不关心发送者和接收者之间的区别,那么您可能希望手动组合它们。

就我的$.02而言,我真的认为python比SQL更好地处理这种逻辑。如果您使用特定于一个DB的查询参数,那么在我看来,这有点违背了ORM的目的

我想试试这样的东西:

messages = Message.objects.filter(Q(sender = request.user)|Q(recipient = request.user))
## Does this need to be 'Q'? ##
然后:

如果要经常查看此集合,可以将其缓存

但最好让合作伙伴成为一个用户域,并在每次发送消息时添加到其中。这样就不需要进行复杂的查询,只需要一个简单的User.partners


我假设您无论如何都需要让用户对象发送消息,因此不会产生额外的开销。

您确定那里没有唯一的记录吗?它们可能具有相同的发件人,但具有不同的PK。在我看来,您的查询将给出您在问题的第二部分中提出的问题。@RobL我已更新了问题。您的评论不清楚,distinct是否总是通过pk返回unique?我认为它将返回值中的unique-based字段。这不是DISTINCT所做的。Distinct返回唯一的行,这就是它在这里所做的。因为每一条消息都是唯一的,所以它会被返回。如果有一个JOIN子句导致返回多行,但它们实际上引用了同一父行,那么DISTINCT将起作用。您可能想使用GROUP_BY。但是要小心,它通常是性能杀手。我不确定您真正想要的是什么,但是如果您想要不同的发件人,那么您应该从该表中选择。如果我们可以从models.py中看到您的模型,那么将更容易帮助您解决。@RobL我需要在django中对特定字段执行一种排序| uniq操作。模型现在有问题。
partners = set()
for m in messages:
    partners.add(m.sender)
    partners.add(m.recipient)