django一对一左连接为空?

发布于 2024-07-29 15:57:30 字数 1094 浏览 10 评论 0原文

我有类似 django 中的模型:

class User(models.Model):
  name = models.CharField(max_length = 128)

class Message(models.Model):
  sender = models.ForeignKey(User, related_name = 'messages_sent')
  recipient = models.ForeignKey(User, related_name = 'messages_recieved')
  subject = models.CharField(max_length = 128)
  body = models.CharField(max_length = 3500)

class Response(models.Model):
  message = models.OneToOneField(Message, primary_key = True)
  reply = models.TextField()

并且我正在尝试获取没有响应的用户的所有消息,我会用 SQL 编写如下:

select * from user u
         join message m on (u.id = m.recipient_id)
         left join response r on (m.id = r.message_id)
where r.message_id = null

我认为执行此操作的自然方法是:

u.messages_recieved.filter(response = None)

u.messages_recieved.filter(response__message_id__isnull = True)

但生成的 SQL 最终总是这样:

WHERE ("project_message"."recipient_id" = 1  AND "project_message"."id" IS NULL)

我是在做一些愚蠢的事情,还是这是 Django 中的一个错误?

I've got models like those in django:

class User(models.Model):
  name = models.CharField(max_length = 128)

class Message(models.Model):
  sender = models.ForeignKey(User, related_name = 'messages_sent')
  recipient = models.ForeignKey(User, related_name = 'messages_recieved')
  subject = models.CharField(max_length = 128)
  body = models.CharField(max_length = 3500)

class Response(models.Model):
  message = models.OneToOneField(Message, primary_key = True)
  reply = models.TextField()

and I'm trying to get all the messages for the user that have no response, something I would write in SQL as:

select * from user u
         join message m on (u.id = m.recipient_id)
         left join response r on (m.id = r.message_id)
where r.message_id = null

I'd think the natural way to do this would be:

u.messages_recieved.filter(response = None)

or

u.messages_recieved.filter(response__message_id__isnull = True)

but the SQL generated always ends up being:

WHERE ("project_message"."recipient_id" = 1  AND "project_message"."id" IS NULL)

Am I doing something stupid, or is this a bug in Django?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

尝蛊 2024-08-05 15:57:30

尝试:

user.messages_recieved.filter(response__isnull=True)

结果查询是:

SELECT "messaging_message"."id", "messaging_message"."sender_id", "messaging_message"."recipient_id", "messaging_message"."subject", "messaging_message"."body" FROM "messaging_message" LEFT OUTER JOIN "messaging_response" ON ("messaging_message"."id" = "messaging_response"."message_id") WHERE ("messaging_message"."recipient_id" = 1  AND "messaging_response"."message_id" IS NULL)

我认为这是正确的。 它确实执行左外连接,然后检查响应消息 id 为空的行。

u.messages_recieved.filter(response=None)

效果也很好。

我正在使用 django 1.1 RC,但这应该可以在 1.0+ 中工作。

Try:

user.messages_recieved.filter(response__isnull=True)

the resulting query is:

SELECT "messaging_message"."id", "messaging_message"."sender_id", "messaging_message"."recipient_id", "messaging_message"."subject", "messaging_message"."body" FROM "messaging_message" LEFT OUTER JOIN "messaging_response" ON ("messaging_message"."id" = "messaging_response"."message_id") WHERE ("messaging_message"."recipient_id" = 1  AND "messaging_response"."message_id" IS NULL)

which I think is proper. It is indeed doing the left outer join and then checking for rows with null response message id.

u.messages_recieved.filter(response=None)

works fine too.

I'm using django 1.1 RC but this should work in 1.0+.

喵星人汪星人 2024-08-05 15:57:30

当我试图实现类似的结果时,我所做的事情是:

u.messages_received.filter(~Q(response__id__gt=0))

Something that I've done when trying to achieve a similar result is:

u.messages_received.filter(~Q(response__id__gt=0))
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文