My problem is excatly with Paginator get_page() method. Here is my view code:
@login_required
def photo_index_default_album(request):
album = Album.get_default_album(request.user)
photo_list = album.photo_set.all()
paginator = Paginator(photo_list, 2) # Show 2 photo per page
page = request.GET.get('sayfa')
photos = paginator.get_page(page)
context = {
'title': album.name,
'photo': photos,
}
return render(request, 'photo/index.html', context)
paginator.get_page(page) is working for only 1. page. After second page it returns a page that has a object_list with an empty QuerySet.
By the way, probably it is a basic knowledge. I just want to know, what is the difference between these 2 assigments:
Option 1:
photo_list = Photo.objects.all()
photo_list.filter(Q(album=album.id))
and
Option2:
photo_list = Photo.objects.filter(album=album.id)
Update: Ok, I understand the difference between 2 options. But my problem is still going on. I updated the code above for query according to your helpful answers.
Problem: This pagination is working only for 1. pagination. If the 'sayfa' variable for page value becomes different than 1, it is not working. In this situation paginator.get_page() returns a page that has a object_list with an empty QuerySet. Checking the photo_list.count(), page, they are correct in every call. Also the paginator variables in template are also true for first and last pages. But I am not showing the images cause of empty return. Why paginator.get_page(page) returns an object_list with empty QuerySet while pagination differ than 1? By the way I am using MongoDB as db backend.
Strange thing: If I assign photo_list = Photo.objects.all(), my template is working as expected. But I want to show only a specific albums' photos. Final update note: Due to lots of images I didn't notice the problem, it was also buggy.
Final Update: (SOLUTION) The reason of wrong query result is a bug about LIMIT-OFFSET queries of Djongo package. I opened an issue, https://github.com/nesdis/djongo/issues/106.
My models:
class Photo(models.Model):
image = models.ImageField()
album = models.ManyToManyField(Album)
class Album(models.Model):
name = models.CharField(max_length=150)
user = models.ForeignKey('accounts.MyUser', verbose_name='Album Owner', on_delete=models.CASCADE)
My template: sorry for inconvenience, it is some long..
{% extends 'base.html' %}
{% block title %}
{{ block.super }} - {{ title }}
{% endblock %}
{% block body %}
<div class="container">
{% for pht in photo %}
<div class="row justify-content-center" style="margin-bottom: 30px">
<div class="col-md-6">
<div class="card">
{% if pht.image %}
<img class="card-img-top img-fluid" src="{{ pht.image.url }}" alt="Card image cap">
{% endif %}
<div class="card-body">
<h5 class="card-title">{{ title }}
<small style="color: #4e555b"> {{ pht.upload_date|timesince }} before</small>
</h5>
{% if request.user.is_authenticated %}
<a href="{{ pht.get_delete_url }}" class="btn btn-danger">Delete</a>
{% endif %}
</div>
</div>
</div>
</div>
{% endfor %}
<div class="row justify-content-center" style="margin-bottom: 30px">
<div class="col-md-6">
<div class="pagination">
<span class="step-links">
{% if photo.has_previous %}
<a href="?sayfa=1{% if request.GET.q %}&q={{ request.GET.q }}{% endif %}">« first</a>
<a href="?sayfa={{ photo.previous_page_number }}{% if request.GET.q %}&q={{ request.GET.q }}{% endif %}">previous</a>
{% endif %}
<span class="current">
Page {{ photo.number }} of {{ photo.paginator.num_pages }}.
</span>
{% if photo.has_next %}
<a href="?sayfa={{ photo.next_page_number }}{% if request.GET.q %}&q={{ request.GET.q }}{% endif %}">next</a>
<a href="?sayfa={{ photo.paginator.num_pages }}{% if request.GET.q %}&q={{ request.GET.q }}{% endif %}">last »</a>
{% endif %}
</span>
</div>
</div>
</div>
</div>
{% endblock %}