问题
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).
回答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