我运行一个实验室注释网站,用户可以使用与疾病,组织类型等相关的标签来注释样本。这是一个来自models.py的简单示例:
from django.contrib.auth.models import User
from django.db import models
class Sample(models.Model):
name = models.CharField(max_length = 255)
tags=models.ManyToManyField('Tag', through = 'Annot')
class Tag(models.Model):
name = models.CharField(max_length = 255)
class Annot(models.Model):
tag = models.ForeignKey('Tag')
sample = models.ForeignKey('Sample')
user = models.ForeignKey(User, null = True)
date = models.DateField(auto_now_add = True)
我正在寻找django的ORM中的查询,该查询将返回两个用户同意相同标签注释的标签。如果我可以提供用户列表来限制我的查询(如果有人只相信User1和User2并希望找到只有他们同意的样本/标签对,那将会很有帮助。)
答案 0 :(得分:1)
我想我理解你的需要。这个让我想到了,谢谢! : - )
我相信等效的SQL查询类似于:
select t.name, s.name, count(user_id) count_of_users
from yourapp_annot a, yourapp_tag t, yourapp_sample s
where a.tag_id = t.id
and s.id = a.sample_id
group by t.name, s.name
having count_of_users > 1
当我想出django模型导航时,我努力不去思考SQL(它往往会妨碍);当谈到聚合查询时,它总是帮助我可视化SQL的内容。
在django,我们现在有aggregations。
以下是我提出的建议:
models.Annot.objects.select_related().values(
'tag__name','sample__name').annotate(
count_of_users=Count('user__id')).filter(count_of_users__gt=1)
结果集将包含标记,样本以及使用所述标记标记所述样本的用户数。
为那些不习惯django聚合的人分开:
models.Annot.objects.select_related()
tag__name
和sample__name
的原因 values('tag__name','sample__name')
annotate(count_of_users=Count('user__id'))
filter(count_of_users__gt=1)
如果您想要添加额外的过滤器来考虑用户应该考虑的因素,您需要这样做:
models.Annot.objects.filter(user=[... list of users...]).select_related().values(
'tag__name','sample__name').annotate(
count_of_users=Count('user__id')).filter(count_of_users__gt=1)
我认为就是这样。
一件事......请注意,我在上面的查询中使用了tag__name和sample__name。但是您的模型未指定标记名称和样本名称为unique。
它们应该是独一无二的吗?将unique=True
添加到模型中的字段定义。
它们不应该是独一无二的吗?您需要在上面的查询中用tag__id和sample__id替换tag__name和sample__name。