Django从不同的模型中进行多对多查找

时间:2015-02-25 18:32:02

标签: django many-to-many lookup

我有一些代表一些公司及其结构的模型。此外,所有模型都可以生成一些通知(注释)。用户可以看到自己的Notes,当然,也看不到其他人。

class Note(models.Model):
    text = models.CharField(...)

class Company(models.Model):
    user = models.ForeignKey(User)
    note = models.ManyToManyField(Note, blank='True', null='True')

class Department(models.Model):
    company = models.ForeignKey(Company)
    note = models.ManyToManyField(Note, blank='True', null='True')

class Worker(models.Model):
    department = models.ForeignKey(Department)
    note = models.ManyToManyField(Note, blank='True', null='True')

class Document(models.Model)
    company = models.ForeignKey(Company)
    note = models.ManyToManyField(Note, blank='True', null='True')

问题是如何收集特定用户的所有Notes以显示它们? 我能做到:

Note.objects.filter(worker__company__user=2)

但它仅适用于由Workers生成的Notes。另一个呢?我可以尝试硬编码所有现有的模型,但如果这样做,十几只小猫会死! 我也尝试使用向后查找,但得到了#34;不支持嵌套查找"。可能是我做错了。

修改 正如我上面提到的,我知道如何通过枚举所有模型(公司,工人等)来做到这一点。但是,如果我将创建一个也可以生成Notes的新模型(例如在另一个应用程序中),我必须在另一个应用程序中更改View中的代码,这样做并不好。

1 个答案:

答案 0 :(得分:1)

您可以使用以下查询获取用户的注释:

例如,让我们认为用户的ID为1,我们希望将其保存在变量x中,以便我们可以在查询中使用它。所以代码将是这样的:

>>x = 1
>>Note.objects.filter(Q(**{'%s_id' % 'worker__department__company__user' : x})|Q(**{'%s_id' % 'document__company__user' : x})|Q(**{'%s_id' % 'company__user' : x})|Q(**{'%s_id' % 'department__company__user' : x})).distinct()

此处我在查询结尾处使用QOR运行distinct()操作以删除重复项。

修改

  

正如我上面提到的,我知道如何通过枚举所有模型来做到这一点   (公司,工人等)。但如果我要创建一个新模型(另一个   例如,也可以生成Notes的应用程序,我必须更改代码   在另一个应用程序的视图中,这并不好。

在我看来,如果你写另一个模型,你怎么想在没有添加新查询的情况下从该模型中获取笔记?这里的每个类(即DepartmentWorker)都分别连接到Company,并且每个类与Note都有自己的m2m关系,并且没有直接连接到User Note个其他类Company除外。另一种方法可能是使用through,但为此你已经改变了现有的模型定义。

另一种解决方案

正如您在评论中提到的,如果您的查询更容易,您愿意更改模型结构,然后您可以尝试以下解决方案:

class BaseModel(models.Model):
    user = models.Foreignkey(User)
    note = models.ManyToManyField(Note)
    reports_to = models.ForeignKey('self', null=True, default=None)


class Company(BaseModel):

    class Meta:
       proxy = True


class Document(BaseModel):

    class Meta:
      proxy = True

#And so on.....

优点:无需为文档/公司等创建单独的表。

对象创建:

>>c= Company.objects.create(user_id=1)
>>c.note.add(Note.objects.create(text='Hello'))
>>d = Document.objects.create(user_id=1, related_to=c)
>>d.note.add(Note.objects.create(text='Hello World'))