使用Django“查找标记的多个实例”;透过「;领域

使用Django“查找标记的多个实例”;透过「;领域,django,Django,我运行了一个实验室注释网站,用户可以在其中使用与疾病、组织类型等相关的标签对样本进行注释。下面是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('T

我运行了一个实验室注释网站,用户可以在其中使用与疾病、组织类型等相关的标签对样本进行注释。下面是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,并希望找到只有他们同意的样本/标记对),那将很有帮助。

我想我了解您需要什么。这个让我想,谢谢!:-)

我相信等效的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,我们现在有

以下是我的想法:

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.选择相关()

  • 正在强制在同一查询中检索与Annot相关的所有表
  • 这就是允许我在values()调用中指定
    tag\uu name
    sample\uu name
值('tag\uuu name'、'sample\uu name')

  • 正在将要检索的字段限制为tag.name和sample.name
  • 这确保了我对客户端计数的聚合将仅按这些字段分组
注释(count\u of\u users=count('user\u id'))

  • 将聚合作为额外字段添加到查询中
filter(用户数=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\uuuuu name和sample\uuuu name。但是您的模型没有指定标记名和示例名是相同的

它们应该是独一无二的吗?将
unique=True
添加到模型中的字段定义中


它们不应该是独一无二的吗?在上面的查询中,您需要用tag\uu id和sample\uu id替换tag\uu name和sample\uu name。

您想要两个用户完全同意还是至少两个用户同意的标签?我想您的意思是两个用户同意对同一个样本的注释。
,正确吗?例如:User1用Tag1注释Sample1 User2用Tag1注释Sample1 User1用Tag2注释Sample1 User2用Tag7注释Sample1 User3用Tag3注释Sample1 User3用Tag7注释Sample1我正在寻找一个将返回Tag1和Tag7的查询。。。仅由至少2个用户注释的标记。找到一种方法来限制用户列表(只接受User1和User2)也是很有帮助的,在这种情况下,它只会返回Tag1looks great。。。有了一个很好的解释,现在检查一下,实际上我把它改为:.values('tag','sample'),这相当于'tag\u id'和'sample\u id'