I've got models like those in django:
我有像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:
我正在尝试为没有响应的用户获取所有消息,我将在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
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:
但生成的SQL总是最终成为:
WHERE ("project_message"."recipient_id" = 1 AND "project_message"."id" IS NULL)
Am I doing something stupid, or is this a bug in Django?
我做了一些愚蠢的事,或者这是Django中的一个错误?
2 个解决方案
#1
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.
我认为这是正确的。它确实在执行左外连接,然后检查具有空响应消息ID的行。
u.messages_recieved.filter(response=None)
works fine too.
工作得很好。
I'm using django 1.1 RC but this should work in 1.0+.
我正在使用django 1.1 RC,但这应该适用于1.0+。
#2
Something that I've done when trying to achieve a similar result is:
我在尝试获得类似结果时所做的一切是:
u.messages_received.filter(~Q(response__id__gt=0))
#1
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.
我认为这是正确的。它确实在执行左外连接,然后检查具有空响应消息ID的行。
u.messages_recieved.filter(response=None)
works fine too.
工作得很好。
I'm using django 1.1 RC but this should work in 1.0+.
我正在使用django 1.1 RC,但这应该适用于1.0+。
#2
Something that I've done when trying to achieve a similar result is:
我在尝试获得类似结果时所做的一切是:
u.messages_received.filter(~Q(response__id__gt=0))