Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Django的并集和交集_Python_Django_Django Models_Django Views_Tagging - Fatal编程技术网

Python Django的并集和交集

Python Django的并集和交集,python,django,django-models,django-views,tagging,Python,Django,Django Models,Django Views,Tagging,简单的模型只是问我的问题 我想知道如何以两种不同的方式使用标记查询博客 标记为“tag1”或“tag2”的博客条目: Blog.objects.filter(tags_in=[1,2]).distinct() 标记为“tag1”和“tag2”的博客对象:? 只标记了“tag1”和“tag2”的博客对象:?? Tag和Blog只是一个例子。您可以将Q对象用于#1: 我相信,并集和交集有点超出了Django ORM的范围,但可以对其进行修改。以下示例来自一个名为called的Django应用程

简单的模型只是问我的问题

我想知道如何以两种不同的方式使用标记查询博客

  • 标记为“tag1”或“tag2”的博客条目:
    Blog.objects.filter(tags_in=[1,2]).distinct()
  • 标记为“tag1”和“tag2”的博客对象:
  • 只标记了“tag1”和“tag2”的博客对象:??


Tag和Blog只是一个例子。

您可以将Q对象用于#1:

我相信,并集和交集有点超出了Django ORM的范围,但可以对其进行修改。以下示例来自一个名为called的Django应用程序,该应用程序提供了该功能:

对于第二部分,基本上是寻找两个查询的联合

# Blogs who have either hockey or django tags.
from django.db.models import Q
Blog.objects.filter(
    Q(tags__name__iexact='hockey') | Q(tags__name__iexact='django')
)
第三部分,我相信你在寻找一个十字路口。看


我已经用Django 1.0对这些进行了测试:

“或”查询:

或者您可以使用Q类:

Blog.objects.filter(tags__name__in=['tag1', 'tag2']).distinct()
“和”查询:


我不确定第三个问题,您可能需要转到SQL来解决。

请不要重新发明轮子和用途,它们完全是为您的用例而设计的。它可以完成您描述的所有查询,甚至更多


如果您需要将自定义字段添加到标记模型中,还可以查看。

这将为您提供帮助

Blog.objects.filter(tags__name='tag1').filter(tags__name='tag2')

Hrm,这个“and”查询看起来像是一个很方便的技巧,只是一开始你不知道有多少次。需要应用过滤器。用户可能正在寻找dog+goat+cat,在这种情况下,您需要。筛选两次。关于“and”查询的动态应用,只需使用:query=query.filter(tags_uname='tagN')迭代标记并累积筛选,我认为第一个示例就可以做到这一点。我在考虑是否需要这种区别。在SQL术语中,您将有2个连接Blog-to-BlogTagLink和BlogTagLink-to-Tag,一个给定的Blog记录将在结果集中多次列出。可能会有帮助(我知道这个问题已经6年了,但我在搜索答案时仍然发现了!)这更多的是where子句中的or问题,而不是实际的SQL联合。如果你想找工会,看看
def get_intersection_by_model(self, queryset_or_model, tags):
    """
    Create a ``QuerySet`` containing instances of the specified
    model associated with *all* of the given list of tags.
    """
    tags = get_tag_list(tags)
    tag_count = len(tags)
    queryset, model = get_queryset_and_model(queryset_or_model)

    if not tag_count:
        return model._default_manager.none()

    model_table = qn(model._meta.db_table)
    # This query selects the ids of all objects which have all the
    # given tags.
    query = """
    SELECT %(model_pk)s
    FROM %(model)s, %(tagged_item)s
    WHERE %(tagged_item)s.content_type_id = %(content_type_id)s
      AND %(tagged_item)s.tag_id IN (%(tag_id_placeholders)s)
      AND %(model_pk)s = %(tagged_item)s.object_id
    GROUP BY %(model_pk)s
    HAVING COUNT(%(model_pk)s) = %(tag_count)s""" % {
        'model_pk': '%s.%s' % (model_table, qn(model._meta.pk.column)),
        'model': model_table,
        'tagged_item': qn(self.model._meta.db_table),
        'content_type_id': ContentType.objects.get_for_model(model).pk,
        'tag_id_placeholders': ','.join(['%s'] * tag_count),
        'tag_count': tag_count,
    }

    cursor = connection.cursor()
    cursor.execute(query, [tag.pk for tag in tags])
    object_ids = [row[0] for row in cursor.fetchall()]
    if len(object_ids) > 0:
        return queryset.filter(pk__in=object_ids)
    else:
        return model._default_manager.none()
Blog.objects.filter(tags__name__in=['tag1', 'tag2']).distinct()
Blog.objects.filter(Q(tags__name='tag1') | Q(tags__name='tag2')).distinct()
Blog.objects.filter(tags__name='tag1').filter(tags__name='tag2')
Blog.objects.filter(tags__name__in=['tag1', 'tag2']).annotate(tag_matches=models.Count(tags)).filter(tag_matches=2)