消息传递系统的Django-ORM查询

2024-09-28 23:44:51 发布

您现在位置:Python中文网/ 问答频道 /正文

我有以下型号的内部消息应用程序:

class MessageThread(models.Model):
    subject = models.CharField(max_length=256, blank=False)

class Message(models.Model):
    thread = models.ForeignKey(MessageThread)
    content = models.CharField(max_length=5000, blank=False)
    timestamp = models.DateTimeField(auto_now_add=True, blank=False)
    sender = models.ForeignKey(User)

class MessageRecipient(models.Model):
    message = models.ForeignKey(Message)
    thread = models.ForeignKey(MessageThread)
    recipient = models.ForeignKey(User)
    status = models.CharField(max_length=20, choices=MESSAGE_STATUS, default="unread")

对于给定用户,要获取我正在执行的线程列表:

^{pr2}$

在ORM中,如果有一条消息包含状态为“deleted”,我该如何删除所有线程?(换句话说,我想得到一个没有包含状态为“已删除”消息的线程的所有线程的列表。)


Tags: falsemessage列表modelmodels线程threadlength
3条回答

我在模型管理器中为此添加了一个方法:

    def get_active_threads(self, user):
        all_threads = MessageRecipient.objects.filter(recipient=user).order_by('-message__timestamp')

        deleted_threads = []
        final_threads = []

        for thread in all_threads:
            if thread.thread not in (deleted_threads or final_threads):
                if thread.status == "deleted":
                    deleted_threads.append(thread.thread)
                else:
                    final_threads.append(thread)

        return final_threads

您可以使用python(如上面所建议的那样)或者让DB为您完成脏工作。在

您需要构造一个包含所有线程的查询集,其中包含针对特定用户的已删除消息,然后构建第二个查询集,该查询集获取第一个用户未包含的所有线程:

delthreads = MessageThread.objects.filter(messagerecipient__recipient=user,
    messagerecipient__status='deleted').distinct()
result = MessageThread.objects.filter(messagerecipient_recipient=user)
    .exclude(messagethread_in=delthreads).distinct()

但是,性能方面(尤其是在大型表上)这会伤害到您。您的模型需要进行一些重组,以便进行更有效的查询。考虑:

^{pr2}$

如果您预计将经常执行此查询,则可以向MessageThread添加一个缓存字段,每当有人删除该线程中的消息时,可以更新该字段:

class MessageThread(models.Model):
    subject = models.CharField(max_length=256, blank=False)
    dirty = models.BooleanField(default=False)

然后,提取一个没有删除消息的线程列表将非常容易。在

^{4}$

简而言之,为什么要在MessageRecipient中使用thread作为字段?您可以通过message到达thread。在

总之,您需要使用exclude()

# breaking up onto multiple lines for readability, not valid python though
MessageThread.objects.filter(messagerecipient__recipient=user)
.exclude(messagerecipient__status='deleted')
.order_by('-message__timestamp').distinct()

相关问题 更多 >