Opened 3 years ago
Last modified 3 years ago
#34067 closed Bug
django.core.Paginator wrong query slicing — at Version 1
| 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 (last modified by )
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
Then I get this result .
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
This happens only on NULL PersonalProfile objects.
I did like so to get OKAY results:
- Added a simple breakpoint is added on
Paginator.pagelike soand that breakpoint is just run then the result is okay
- changed paginate_by to 10
- changed
order_byinget_querysetto-pk
- call again the
page = paginator.page(page_number)
P.S. That is also happening in django 2.2
Change History (3)
by , 3 years ago
| Attachment: | images.zip added |
|---|
comment:1 by , 3 years ago
| Description: | modified (diff) |
|---|
Some of the images