I'm trying to build a simple Django gallery that allows photos to be added to an album. Everything thus far is working fine (upload photo, add to album, paginated all photos listing, photo details/display pages, etc), until I try to display the 'album' pages. I can get the page to render the the album and all of the associated photos, but if I try to paginate the album, things start to get weird.
Here are my models:
# models.py
class Albums(models.Model):
id = models.AutoField(primary_key=True, unique=True)
name = models.CharField(max_length=500)
slug = models.SlugField(max_length=500, unique=True)
description = models.TextField(blank=True, null=True)
def __str__(self):
return self.name
def save(self, *args, **kwargs):
if not self.slug:
self.slug = slugify(self.name)
return super().save(*args, **kwargs)
class Photos(models.Model):
id = models.AutoField(primary_key=True, unique=True)
album = models.ForeignKey(
Albums, on_delete=models.SET_NULL, null=True, blank=True, verbose_name="Album"
)
photo = models.ImageField(upload_to="photos/")
slug = models.CharField(max_length=16, null=False, editable=False) # I know I'm not using a SlugField here; that's on purpose
title = models.CharField(max_length=500)
description = models.TextField(blank=True, null=True)
upload_date = models.DateTimeField(
default=timezone.now, verbose_name="Date uploaded"
)
def __str__(self):
return self.title
def save(self, *args, **kwargs):
[...] # stuff to get the image's EXIF data and use that to set the slug
self.slug = str(datetime.strftime(img_date, "%Y%m%d%H%M%S"))
[...] # plus a bunch of other stuff that happens on save, not important here
super(Photos, self).save()
def delete(self, *args, **kwargs):
[...] # a bunch of stuff that happens on delete, not important here
super(Photos, self).delete()
And the view that's making me miserable:
# views.py
class PhotoAlbum(DetailView):
context_object_name = "album"
model = Albums
slug_field = "slug"
template_name = "page.html"
def get_photos(self, **kwargs):
# get the integer id of the album
a = Albums.objects.filter(slug=self.kwargs["slug"])
a_id = a.values()[0]["id"]
# get the list go photos in that album
photos = Photos.objects.all().order_by("-capture_date").filter(album_id=a_id)
return photos
def get_context_data(self, **kwargs):
context = super(PhotoAlbum, self).get_context_data(**kwargs)
context["photos"] = self.get_photos()
return context
These work in a basic template...
# album.html
<h2>{{ album.name }}</h2>
<p>{{ album.description }}</p>
<ul>
{% for photo in photos %}
<li><a href="{% url 'photo_detail' photo.slug %}">{{ photo.title }}</a></li>
{% endfor %}
</ul>
...but if I try to paginate the photos by changing...
photos = Photos.objects.all().order_by("-capture_date").filter(album_id=a_id)
...to...
photos = Paginator(Photos.objects.all().order_by("-capture_date").filter(album_id=a_id), 10)
...I get nothing.
In searching around, almost all of the questions I've seen relating to pagination are for DRF, so have kind of hit a wall here. I had all sorts of trouble getting the photo-to-album relationship to display (the get_photos()
function), so am guessing part of my problem lies with that. Any suggestions on how to get this working?
CodePudding user response:
Paginator
will give you a paginator object, not the objects you are paginating. To get the objects, you first need to specify the page, so for example:
paginator = Paginator(Photos.objects.all().order_by("-capture_date").filter(album_id=a_id), 10)
photos = paginator.page(1)
photos
here will then contain Photos
objects that are on page 1.