我有一些代表一些公司及其结构的模型。此外,所有模型都可以生成一些通知(注释)。用户可以看到自己的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中的代码,这样做并不好。
答案 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()
此处我在查询结尾处使用Q和OR
运行distinct()
操作以删除重复项。
修改强>
正如我上面提到的,我知道如何通过枚举所有模型来做到这一点 (公司,工人等)。但如果我要创建一个新模型(另一个 例如,也可以生成Notes的应用程序,我必须更改代码 在另一个应用程序的视图中,这并不好。
在我看来,如果你写另一个模型,你怎么想在没有添加新查询的情况下从该模型中获取笔记?这里的每个类(即Department
,Worker
)都分别连接到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'))