使用外键作为参数过滤Django中的对象

时间:2014-05-16 15:29:02

标签: python django filter

我正在使用Django教程来帮助您构建一个Poll应用程序。我完成了所有教程,现在我正在尝试添加一些额外的功能来了解有关django的更多信息。

我有2个模型PollChoice。选择模型有一个外键调查,所以我可以在每个民意调查中有几个选择。我想要做的是通过删除那些根本没有任何选择的民意调查来过滤我的索引页面上显示的民意调查。我想我可以用get_queryset方法做​​到这一点,但我不知道如何使用filter方法来实现这一点。任何人都可以帮我这个吗?

我的模特:

from django.utils import timezone
from django.db import models
import datetime



from django.contrib.auth.models import AbstractUser
# Create your models here.

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

def __unicode__(self):  # Python 3: def __str__(self):
    return self.question

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):
   poll = models.ForeignKey(Poll)
   choice_text = models.CharField(max_length = 200)
   votes = models.IntegerField(default=0)

def __unicode__(self):  # Python 3: def __str__(self):
    return self.choice_text

我的索引视图

class IndexView(generic.ListView):
template_name = 'polls/index.html'
context_object_name = 'latest_poll_list'

def get_queryset(self):
    """
    Return the last five published polls (not including those set to be
    published in the future) and remove polls with no choices.
    """
    # Removing Polls with no Choices

    #Filtering by recent posts (just one day old)
    p= Poll.objects.filter(
        pub_date__lte=timezone.now()
    ).order_by('-pub_date')[:5]
    return p

2 个答案:

答案 0 :(得分:3)

一个解决方案是annotations

from django.db.models import Count

polls_with_choices = Poll.objects.annotate(num_choices=Count('choice'))
                                 .filter(num_choices__gt=0)

基本上,&#39;注释&#39; queryset方法将生成SQL,将计算列添加到查询结果中。然后,您可以过滤该计算列的内容。

答案 1 :(得分:2)

您可以使用get_queryset方法。如果没有这样的选择,您可以排除任何结果:

p = Poll.objects.filter(pub_date__lte=timezone.now(), choices__isnull=False)