Django photologue images and queryset

263 Views Asked by At

I've added photologue to my project, because it does 99% of the things I was trying to achieve by myself.

Now I need to connect the uploaded images and images in galleries to my posts. This is why I've added a ManyToMany field to the photologue Photo model

Class ImageModel(models.Model):
     post_images =  models.ManyToManyField(Post, blank=True)

And will do the same to the Gallery model

class Gallery(models.Model):
     post_gallery =  models.ManyToManyField(Post, blank=True)

Now my idea is to be able to add a gallery and/or specific images to my post . Both options should be available.

The queryset I would like to have is to get all the individual images, that are attached to the post and also all the images in the gallery if a gallery is attached. Then to pass and render them to the page in some sort of gallery (Slider, carousel or something else). I'd like to be able to get them in the template with one for loop, so I think the queryset have to be one.

I have a view that renders the specific page type and I don't know if I should include the queryset and context in this function or to create a new one for the images. And how to do it.

def post(request, slug):
    post = get_object_or_404(Post, post_slug=slug)
    context = {
        'post': post,
     }
    return render(request, 'project_name/post.html', context)

I hope I have explained what I'd like to do. Django is new to me and querysets are still a bit complex.

2

There are 2 best solutions below

4
Hvitis On

Shouldn't you try adding galleriesto posts from posts?

from photologue.models import Gallery
class Post(models.Model):
    gallery = models.ManyToManyField(Gallery, blank=True )

#Edit ___ @TwinDewey In this case you need to make a query in Views to get the Galleries when showing Post details.

galleries = gallery.posts.all() 
gal = [] 
for excercise in excercises: 
    gal.append(Gallery.objects.filter(gallery__name=self.post.title)) 

Or you can make a query and merge it with the Post context using

from itertools import chain 
list(chain(post_context,Gallery.objects.filter(gallery__name=self.post.title))) 

That´s for gallery. Posts would have another query.

0
AudioBubble On

You can use union to group the photos tied to the post itself and inside the gallery. The trick is to get the right models so they are the same objects:

from django.db import models
from photologue.models import Gallery, Photo


class Post(models.Model):
    title = models.CharField(max_length=100)
    published_at = models.DateTimeField(blank=True, null=True)
    text = models.TextField()
    photos = models.ManyToManyField(Photo, related_name='posts')
    galleries = models.ManyToManyField(Gallery, related_name='posts')

    @property
    def all_images(self):
        # Create a number of querysets that have photos from selected galleries
        # ..note:
        #   .only() is used to trim down on the fields fetched from the database.
        #   .prefetch_related() is used to eliminate extra queries during iteration
        qs = []
        for gallery in self.galleries.prefetch_related('photos').only('photos'):  # type: Gallery
            qs.append(gallery.photos.only('image', 'title'))

        return self.photos.only('image', 'title').union(*qs)      

Now you can use it in a template like so:

{% for photo in post.all_images %}
    <img src="{{ photo.image.url }}" alt="{{ photo.title }}" />
{% endfor %}