I've edited the code from the tutorial for the index view to look like this:
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, or those without choices).
"""
return Poll.objects.filter(
pub_date__lte=timezone.now(), choice__choice_text__isnull=False
).order_by('-pub_date')[:5]
But now my index looks like this:
- What're you up to?
- What're you up to?
- What're you up to?
- Whats up?
- Whats up?
How has this happened? And how should I fix this?
(p.s. I had no idea who to use filter, so I copied code from this question. Is this why it's not worked? How does the double underscore __
notation work in filter?)
Edit: I've checked the Admin view, and there only seems to be one of each poll in the DB (I've not checked directly), but I'm confident that the way its set up I couldn't have multiple polls with the same ID (which is the case, all the 'What're you up to?' polls have ID 2, all the 'Whats up?' polls have ID 1).
Adding distinct()
(as Wolf suggests) to the chain of methods does indeed work. I think the crux of the issue is that the eventual DB query returns the combination of Polls that are recent (pub_date__lte=timezone.now()
) AND polls with non-null Choices (choice__choice_text__isnull=False
) regardless of overlap.
I'm not sure of a better way to prevent this at the root than just using distinct()
. I tried chaining the filters and that seems to make no difference.
It turns out distinct is the correct solution:
"I did a search for the explanation, and it appears that when a query spans multiple table it can return duplicates. distinct is the proper solution here."
– Ludovic Viaud in a comment
来源:https://stackoverflow.com/questions/26978102/filtering-out-choiceless-polls-in-the-django-tutorial-causes-polls-in-the-index