Why .filter() in django returns duplicated objects?

后端 未结 3 597
悲&欢浪女
悲&欢浪女 2021-01-17 12:03

I\'ve followed django tutorial and arrived at tutorial05.

I tried to not show empty poll as tutorial says, so I added filter condition like this:

cla         


        
相关标签:
3条回答
  • 2021-01-17 12:39

    choice__isnull causes the problem. It leads to join with choice table (to weed out questions without choices), that is something like this:

    SELECT question.*
      FROM question
      JOIN choice
        ON question.id = choice.question_id
     WHERE question.pub_date < NOW()
    

    You can inspect query attribute of QuerySet to be sure. So if you have one question with two choices, you will get that question two times. You need to use distinct() method in this case: queryset.distinct().

    0 讨论(0)
  • 2021-01-17 12:41

    Because you created two objects with same properties. If you want to ensure uniqueness, you should add validation in clean and add unique index on identifier field too.

    Besides filter returns all the objects that match the criteria, if you are expecting only one item to be returned, you should use get instead. get would raise exception if less or more than 1 item is found.

    0 讨论(0)
  • 2021-01-17 12:42

    A little late to the party, but I figured it could help others looking up the same issue. Instead of using choice__isnull=False with the filter() method, use it with exclude() instead to exclude out any questions without any choices. So your code would look something like this:

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

    By doing it this way, it will return only one instance of the question. Be sure to use choice_isnull=True though.

    0 讨论(0)
提交回复
热议问题