如何根据超模型的属性过滤模型对象?

How can you filter model objects by attributes of their supermodel?

为了开始使用 Django,我做了 Django 本身提供的介绍。在第 5 部分,您为 viewsmodels 写了一些 tests。之后,他们会为您提供更多 tests 的想法。我的问题就是从这里开始的。他们建议您只显示 QuestionsChoices 的数量大于 0。我不知道该怎么做。我当前的代码可以在 https://github.com/byTreneib/django.git. The Django tutorial can be found at https://docs.djangoproject.com/en/3.0/intro/tutorial05/

找到

models.py

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


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):
        return timezone.now() >= self.pub_date >= timezone.now() - datetime.timedelta(days=1)


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

    def __str__(self):
        return self.choice_text

views.py

from django.shortcuts import render
from django.http import HttpResponse, Http404, HttpResponseRedirect
from django.template import loader
from django.shortcuts import render, get_object_or_404
from django.db.models import F
from .models import Question, Choice
from django.urls import reverse
from django.views import generic
from django.utils import timezone


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

    def get_queryset(self):
        return Question.objects.filter(pub_date__lte=timezone.now()).filter().order_by('-pub_date')[:5]


class DetailView(generic.DetailView):
    model = Question
    template_name = 'polls/detail.html'

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


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

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


def vote(request, question_id):
    question = get_object_or_404(Question, pk=question_id)
    try:
        selected_choice = question.choice_set.get(pk=request.POST['choice'])
    except (KeyError, Choice.DoesNotExist):
        return render(request, 'polls/detail.html', {'question': question, 'error_message': "No choice selected!"})
    else:
        selected_choice.votes = F('votes') + 1
        selected_choice.save()
        return HttpResponseRedirect(reverse('polls:results', args=(question.id, )))

您可以使用 django 的 RelatedManager 查看所有 Choice 个指向 Question 的实例。阅读更多 here.

视图将是这样的:

class ListView(generic.ListView):
    model = Question

    def get_queryset(self):
        return Question.objects.filter(choice__isnull = False)