Reputation: 15548
I've been following Django starter tutorial ( https://docs.djangoproject.com/en/1.8/intro/tutorial05/ )
I decided to make some modifications to test my skills as of now.
Specifically I intend to implement a custom get_queryset for ResultsView generic view.
Something like this:
# 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 ...
Basically my goal is to return Questions' choices only for choices with at least 1 vote.
So I tried in Django's shell something like this:
# Django shell
q = Question.objects.get(pk=1)
q.choice_set.filter(votes=1)
[<Choice: Not much>]
Here I get question with pk = 1, then filter based on choice_set (of Choice model, whose fk refers to Question model).
I'm trying to figure out how to implement this in my views.py, so that it returns Questions' content (i.e. choices) only for choices with 1+ votes (i.e. displaying all choices with related votes but choices with 0 votes).
Just for completeness here is the actual template (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
# 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
Upvotes: 1
Views: 5910
Reputation: 1387
I think __ relations should do you.
Something like this maybe?
def get_queryset(self):
return Question.objects.filter(choices__votes__gte=1)
EDIT:
You actually want to overload get_object. See the definitions of get() and get_object here: https://ccbv.co.uk/projects/Django/1.8/django.views.generic.detail/DetailView/
Specifically, something like:
pk = self.kwargs.get(self.pk_url_kwarg, None)
Choice.objects.filter(question__pk=pk, votes__gte=1)
What you are doing is a little weird because detail view usually works on one object, but this should work.
Upvotes: 3