Opened 2 years ago

Last modified 2 years ago

#34067 closed Bug

django.core.Paginator wrong query slicing — at Initial Version

Reported by: Hristo Trendafilov Owned by: nobody
Component: Core (Other) Version: 3.2
Severity: Normal Keywords: Paginator, slice, queryset
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

A have a ListView defined like so:

class AllPracticesListView(LoginRequiredMixin, PermissionRequiredMixin, ListView, ToolBoxFunctions):
    template_name = 'practice_list.html'
    model = Practice
    paginate_by = 6
    permission_required = 'customauth.access_practices'

    def get_queryset(self):
        qs = self.get_all_practices_by_user().order_by(
            'company_branch__pk', 'practice_profile__personal_profile__last_name').prefetch_related('practice_profile')
        
        # method < get_all_practices_by_user > is a toolbox method that returns:  
        # Practice.objects.filter(company_branch__owner=self.request.user).order_by('pk')

        return qs

Models are defined like so:

      
 class Practice(models.Model):           
                company_branch = models.ForeignKey(
                         CompanyBranch,
                         on_delete=models.PROTECT,
                         related_name='practices',
                    )                
                # CompanyBranch model has an owner field which ForeignKey to the user model       
                
                practice_profile = models.ForeignKey(
                    PracticeProfile,
                    on_delete=models.PROTECT,
                    related_name='practices',
                )
      
class PracticeProfile(models.Model):               
                    personal_profile = models.ForeignKey(
                        PersonalProfile,
                        on_delete=models.PROTECT,
                        blank=True,
                        null=True,
                    )
                    # PersonalProfile model has a field called < last_name > 

Or schematically:

Practice object relations: 
      -> CompanyBranch 
      -> PracticeProfile 
          -> PersonalProfile /*NULLABLE RELATION/
       

When the code is run, the view does not display results correctly.

I did like so to get the WRONG result:
Added a breakpoint on Paginator._get_page return statement

Queryset is passed okay and is available in
Paginator.object_list

But in the args of Paginator._get_page the queryset is totally different than expected / should be a slice from the first six elements of Paginator.object_list /

I have tried to add a breakpoint like so https://imgur.com/SdaQUt6
Then I get this result https://imgur.com/5zzLNV0.

As you can see, PKs 1632, 1624, etc. are missing, objects are different/marked red and purple/, and are actually removed and never shown in the view.

If you run slice manually at this point - everything is again fine https://imgur.com/yvn8KMO
This happens only on NULL PersonalProfile objects.

I did like so to get OKAY results:

  1. Added a simple breakpoint is added on Paginator.page like so https://imgur.com/d7J5BMZ and that breakpoint is just run then the result is okay https://imgur.com/ILDHAMN
  1. changed paginate_by to 10
  1. changed order_by in get_queryset to -pk
  1. call again the page = paginator.page(page_number)

Change History (2)

by Hristo Trendafilov, 2 years ago

Attachment: images.zip added

Some of the images

by Hristo Trendafilov, 2 years ago

Attachment: images2.zip added

Other images

Note: See TracTickets for help on using tickets.
Back to Top