姜戈 |如何与两个模型建立反向关系

Posted

技术标签:

【中文标题】姜戈 |如何与两个模型建立反向关系【英文标题】:Django | How to make a reverse Relationship with two models 【发布时间】:2019-03-01 03:40:59 【问题描述】:

我想做一个票务系统。我有主模型(TicketSystem)和一个包含用户消息的模型(TicketSystem_Messages)。

在模型“TicketSystem_Messages”中是模型“TicketSystem”的ForeignKey。

这是我的代码:

class TicketSystem(models.Model):
    subject = models.CharField(_('Subject'),max_length=30, blank=False, default="N/A")
    message = models.TextField(_('Message'), null=False, blank=False)
    created_date = models.DateTimeField(_('Date'), default=datetime.utcnow().replace(tzinfo=utc))
    fertig_date = models.DateTimeField(_('Date'), default=datetime.utcnow().replace(tzinfo=utc))

class TicketSystem_Messages(models.Model):
    user_name = models.ForeignKey(User)
    status = models.ForeignKey(TicketSystem_Status)
    ticketid = models.ForeignKey(TicketSystem)
    message = models.TextField(_('Message'), null=False, blank=False)
    created_date = models.DateTimeField(_('Sent'), default=datetime.utcnow().replace(tzinfo=utc))

目前我得到没有消息的门票:

sql_TicketSystem = TicketSystem.objects.filter(id=kwargs['pk'])

我想像这样进行 LEFT JOIN

SELECT * FROM TicketSystem LEFT JOIN TicketSystem_Messages ON Ticketsystem.id = TicketSystem_Messages.ticketid

我听说过一些关于“select_related”和“prefetch_related”的东西并尝试过,但它不起作用。

【问题讨论】:

我不是 SQL 专家,所以 join 对我来说没有多大意义。你拿到了sql_TicketSystem = TicketSystem.objects.filter(id=kwargs['pk']) 的票,你想获取与该票号相关的所有TicketSystem_Messages 吗? 问题是一个ticket并不总是有消息,因此如果ticket没有消息就找不到ticket 拿到票后TicketSystem.objects.filter(id=kwargs['pk'])可以查询到所有与之相关的消息。它将返回查询集中或空查询集中的所有相关消息。使用sql_TicketSystem.ticketsystem_messages_set.all() 'QuerySet' 对象没有属性 'TicketSystem_Messages_set' ticketsystem_messages_set 不是TicketSystem_Messages_set 【参考方案1】:

在 Django 中,您可以在任一方向遍历模型关系,而不是使用原始 SQL 连接,而不管它们在数据库中是如何表示的。

要查找给定TicketSystem 实例的所有消息:

my_ticket = TicketSystem.objects.get(id=0) # or something
my_ticket_messages = my_ticket.ticketsystem_messages_set.all() # or do other filters here

使用queryset 查找所有消息:

TicketSystem_Messages.objects.filter(ticketId=my_ticket)

要查找包含多条消息的所有票证:

from django.db import Count
TicketSystem.objects.annotate(message_count=Count('ticketsystem_messagess')).filter(message_count__gt=1)

【讨论】:

【参考方案2】:

如果我想列出模型“TicketSystem_Messages”中具有最后状态的所有票证,它不起作用。因此,使用“TicketSystem.objects.get”它可以毫无问题地工作。

例子:

sql_TicketSystem = TicketSystem.objects.all()
sql_TicketSystem_Messages = sql_TicketSystem.ticketsystem_messages_set.all()

更新:

% for data in sql_TicketSystem %
      data.subject 
     % for msg in data.ticketsystem_messages_set.all %
          msg.status
     % empty %
          Unknown
     % endfor %
% endfor %

这行得通:-)

【讨论】:

以上是关于姜戈 |如何与两个模型建立反向关系的主要内容,如果未能解决你的问题,请参考以下文章

姜戈。覆盖模型的保存

在这种情况下,我如何建立核心数据模型以及与啥关系?

如何与类型存储在 db 中的模型建立一对多关系

姜戈。如何优化数据库查询?

如何在 django 模型中进行 2 层深度反向关系?

VS2015 + SQL Server 反向生成实体模型