【问题标题】:Django's Generic Views: how to filter get_queryset based on foreign class attributes?Django的通用视图:如何根据外部类属性过滤get_queryset?
【发布时间】:2015-11-13 00:36:39
【问题描述】:

我一直在关注 Django 入门教程 (https://docs.djangoproject.com/en/1.8/intro/tutorial05/)

我决定从现在开始进行一些修改以测试我的技能。

具体来说,我打算为 ResultsView 通用视图实现自定义 get_queryset

类似这样的:

# views.py
class ResultsView(generic.DetailView):
    model = Question
    template_name = 'polls/results.html'

    def get_queryset(self):
        '''
        Make sure we are displaying results for choices which have 1+ votes
        '''
        return Question.objects.get ...

基本上,我的目标是仅针对至少 1 票的选择返回问题的选择。

所以我在 Django 的 shell 中尝试了这样的东西:

# Django shell
q = Question.objects.get(pk=1)
q.choice_set.filter(votes=1)
[<Choice: Not much>]

这里我得到 pk = 1 的问题,然后根据choice_set(Choice 模型的 fk 指的是 Question 模型)进行过滤。

我试图弄清楚如何在我的 views.py 中实现这一点,以便它仅返回问题的内容(即选择),仅针对具有 1+ 票的选择(即显示所有选择有相关票数,但选择票数为 0)。

为了完整起见,这里是实际模板(polls/results.html):

<h1>{{ question.question_text }}</h1>

<ul>
{% for choice in question.choice_set.all %}
    <li>{{ choice.choice_text }} -- {{ choice.votes }} vote{{ choice.votes|pluralize }}</li> {# pluralize used to automatically add "s" for values with 0 or 2+ choice.votes #}
{% endfor %}
</ul>

<a href="{% url 'polls:detail' question.id %}">Vote again?</a>

模型

# models.py
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

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

【问题讨论】:

    标签: python django django-models django-queryset


    【解决方案1】:

    我认为__关系应该做你。

    可能是这样的吗?

    def get_queryset(self):
    
        return Question.objects.filter(choices__votes__gte=1)
    

    编辑:

    您实际上想要重载 get_object。在此处查看 get() 和 get_object 的定义:https://ccbv.co.uk/projects/Django/1.8/django.views.generic.detail/DetailView/

    具体来说,类似:

    pk = self.kwargs.get(self.pk_url_kwarg, None)
    Choice.objects.filter(question__pk=pk, votes__gte=1)
    

    你所做的有点奇怪,因为细节视图通常适用于一个对象,但这应该可以。

    【讨论】:

    • 听起来不错。但是我收到此错误“get() 返回了多个问题 - 它返回了 2!”如何返回(在 get_queryset 中)具有 1+ 票的选项,用于应用视图的特定问题?
    • 如果视图有问题 PK(或类似问题),您可能会这样做:Choice.objects.filter(question__pk=X, votes__gte=1)。这取决于您的型号。如果您发布它们,将更容易回答。
    • 我认为 pk 是隐含的。我刚刚用两个涉及的模型修改了我的问题。有什么线索吗?
    • 虽然效果与我想要的不完全一样(我猜我会在模板级别实现它)我最终通过使用 distinct() 解决了。问题是,当以 1+ 票对每个选项执行查询时,相同的问题被返回到数组中。感谢您的努力:)
    猜你喜欢
    • 2016-06-10
    • 1970-01-01
    • 1970-01-01
    • 2023-03-31
    • 2010-12-31
    • 2017-02-04
    • 1970-01-01
    • 2021-09-04
    • 1970-01-01
    相关资源
    最近更新 更多