django过滤外键对象中的字段

时间:2014-11-03 06:02:02

标签: python django

鉴于django民意调查教程中的以下模型:

class Question(models.Model):
    question_text = models.CharField(max_length=200)
    pub_date = models.DateTimeField('date published')

    def __str__(self):
        return self.question_text

    def was_published_recently(self):
        now = timezone.now()
        return now - datetime.timedelta(days=1) <= self.pub_date <= now
    was_published_recently.admin_order_field = 'pub_date'
    was_published_recently.boolean = True
    was_published_recently.short_description = 'Published recently'


class Choice(models.Model):
    question = models.ForeignKey(Question)
    choice_text = models.CharField(max_length=200)
    votes = models.IntegerField(default=0)

    def __str__(self):
        return self.choice_text

我希望能够排除没有的问题和教程中建议的选择。我一直在玩Filter,但我无法弄明白,我试过了:

def get_queryset(self):
    return Question.objects.filter(pub_date__lte=timezone.now(), choice__count__gt=0)

但我正在

Relation fields do not support nested lookups

如何根据没有任何选择的问题进行过滤?

4 个答案:

答案 0 :(得分:8)

您也可以使用如下

from django.db.models import Count

......

def get_queryset(self):
    return Question.objects.annotate(num_choice=Count('choice')).filter(pub_date__lte=timezone.now(), num_choice=0)

答案 1 :(得分:2)

使用choice__isnull = True,其中choice是related_name。

def get_queryset(self):
    return Question.objects.filter(pub_date__lte=timezone.now(), choice__isnull=False)

答案 2 :(得分:1)

您需要使用choice__isnull=False而不是像

那样计算
return Question.objects.filter(pub_date__lte=timezone.now(), 
                               choice__isnull=False)

请注意,您可能会获得可以使用.distinct()合并的重复记录。

答案 3 :(得分:0)

我会将模型更改为:

class Question(models.Model):
    choices = models.ManyToManyField('Choice')
    ...

class Choice(models.Model):
    question = models.ForeignKey(Question)
    ...

查询将像

questions = Question.objects.annotate(num_of_choices=Count('choices')).filter(pub_date__lte=timezone.now(), num_of_choices=0)