使用复杂过滤器

时间:2017-07-06 15:03:35

标签: python django orm

我有以下型号:

...
from django.contrib.auth.models import User


class TaxonomyNode(models.Model):
    node_id = models.CharField(max_length=20)
    name = models.CharField(max_length=100)
    ...


class Annotation(models.Model):
    ...
    taxonomy_node = models.ForeignKey(TaxonomyNode, blank=True, null=True)


class Vote(models.Model):
    created_by = models.ForeignKey(User, related_name='votes', null=True, on_delete=models.SET_NULL)
    vote = models.FloatField()
    annotation = models.ForeignKey(Annotation, related_name='votes')
    ...

在应用中,User可以为Vote实例生成Annotation。 对于User实例,Annotation 只能投票一次。 我希望获得一个TaxonomyNode的查询集,User仍然可以注释其中Annotation中的至少一个def user_can_annotate(node_id, user): if Annotation.objects.filter(node_id=node_id).exclude(votes__created_by=user).count() == 0: return False else: return True def get_categories_to_validate(user): """ Returns a query set with the TaxonomyNode which have Annotation that can be validated by a user """ nodes = TaxonomyNode.objects.all() nodes_to_keep = [node.node_id for node in nodes if self.user_can_annotate(node.node_id, user)] return nodes.filter(node_id__in=nodes_to_keep) categories_to_validate = get_category_to_validate(<user instance>) 。现在,我这样做:

TaxonomyNode

我想在一个查询中有一种方法可以做到这一点,这将大大加快这个过程。简而言之,我想从 $("body").on("click", ".Prodotto", function(){ if($(this).is(":empty")){ $(this).addClass("empty-content"); } }); 集合中排除所有已经由用户投票一次全部注释的节点。

我知道如何做到这一点?使用django ORM还是在SQL中? 我有Django版本1.10.6

2 个答案:

答案 0 :(得分:0)

尝试使用它:

#SQL query
unvoted_annotations = Annotation.objects.exclude(votes__created_by=user).select_related('taxonomy_node')

#remove duplicates
taxonomy_nodes=[]
for annotation in unvoted_annotations:
    if annotation.taxonomy_node not in taxonomy_nodes:
        taxonomy_nodes.append(annotation.taxonomy_node)

只有一个SQL查询,因为select_related将在单个查询中返回相关的taxonomy_node。另外,可能有更好的方法来删除重复项,例如:使用 .distinct()

答案 1 :(得分:0)

到目前为止我做了什么:

taxonomy_node_pk = [a[0] for a in Annotation.objects.exclude(votes__created_by=user)
    .select_related('taxonomy_node').values_list('taxonomy_node').distinct()]

nodes = TaxonomyNode.objects.filter(pk__in=taxonomy_node_pk)

我正在进行两次查询,但第二次查询费用不高。 它比我原来的版本快得多。 我做的仍然不是真的很美。无法直接从Annotation集中获取TaxonomyNode的查询集?然后在其中应用disctinct()?