【问题标题】:django join querysets from multiple tablesdjango join 来自多个表的查询集
【发布时间】:2010-06-14 10:03:15
【问题描述】:

如果我对多个表有查询,例如:

d = Relations.objects.filter(follow = request.user).filter(date_follow__lt = last_checked)
r = Reply.objects.filter(reply_to = request.user).filter(date_reply__lt = last_checked)
article = New.objects.filter(created_by = request.user)
vote = Vote.objects.filter(voted = article).filter(date__lt = last_checked)

我想显示所有按日期排序的结果(我的意思是不列出所有回复,然后列出所有投票等)。 不知何故,我想在一个查询集中“加入所有这些结果”。 有可能吗?

【问题讨论】:

  • 你能说出你为什么要这样做吗?我们可能会为您提供替代解决方案...
  • 因为:1.我有一个通知列表,我想为用户显示所有“新通知”,按照事件发生的顺序(我的意思是先回复,然后投票等)。另外,我想按天订购所有这些通知(而且只有当我有所有这些通知的查询集时才可能)。和 2. 第二个原因 - 我在其他地方有一个搜索功能,在 UserProfile 的“名称字段”中有一个查询集,我想为用户表的“用户名”添加一个 qset,以便它能够搜索两者。非常感谢!
  • 我认为,如果您不想像 Sébastien Piquemal 提到的那样更改模型的架构,您只能将所有对象放在一个列表中并对其进行排序,但不能使用查询集。跨度>
  • 嗯……这也是个主意。我会先尝试这个,如果它工作正常,我会保留它,并记住超级类的解决方案来解决另一个问题。非常感谢!

标签: django join django-queryset


【解决方案1】:

看来你需要不同的对象才能有共同的操作......

1) 在这种情况下,在超类中抽象这些属性可能会更好...我的意思是您可以拥有一个定义 user 字段的 Event 类,并且您的所有其他事件类都将是子类这个。

class Event(model.Model):
    user = models.ForeignKey(User)
    date = ...

class Reply(Event):
    #additional fields

class Vote(Event):
    #additional fields

那么你就可以做到以下几点

Event.objects.order_by("date") #returns both Reply, Vote and Event

查看http://docs.djangoproject.com/en/1.2/topics/db/models/#id5 以获取有关模型继承的信息。

2) 你也可以有一个Event 模型与另一个对象的通用关系。这对我来说听起来更干净,因为Vote 在概念上不是“事件”。退房:http://docs.djangoproject.com/en/dev/ref/contrib/contenttypes/#id1

无论如何,我认为您的问题是设计问题

【讨论】:

  • 无论如何,如果我使用“子类”方法,我应该如何更改我的(以上)查询以填充新创建的模型,并获取变量来操作我的模板?我在 djangoproject 参考中没有看到示例。谢谢!
  • 实际上,正如我所写和其他人所证实的那样,我认为解决方案 2 更好。
【解决方案2】:

除了 Sebastien 的提议 2:Django 实际上还有一些内置功能,您可以为此“滥用”;对于管理员来说,它已经有一个模型可以记录用户的操作并通过通用外键关系引用对象,我认为您可以对该模型进行子类化并将其用于您的目的:

from django.contrib.admin.models import LogEntry, ADDITION
from django.utils.encoding import force_unicode
from django.contrib.contenttypes.models import ContentType

class MyLog(LogEntry):
    class Meta(LogEntry.Meta):
        db_table_name = 'my_log_table' #use another name here 

def log_addition(request, object):
    LogEntry.objects.log_action(
        user_id         = request.user.pk,
        content_type_id = ContentType.objects.get_for_model(object).pk,
        object_id       = object.pk,
        object_repr     = force_unicode(object),
        action_flag     = ADDITION
    )

您现在可以使用log_addition(request, object) 记录您的所有通知等,并过滤日志表而不是出于您的目的!如果您还想记录更改/删除等,您可以为此创建一些辅助函数!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-10-29
    • 1970-01-01
    • 2021-02-15
    • 2016-10-26
    • 2021-09-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多