I need to understand a bit better how do FK/m2m relationships work.
I’ve prepared Images model for uploading images and it has an additional feature – it can be categorized by adding to a specific gallery (m2m relation to gallery).
To access gallery name I just had to do a query set for example:
Images.objects.filter(gallery__gallery_name = '')
I’d like to reverse the query a little bit so from Gallery model I can access pictures which are in specific gallery (gallery_name).
How I can do that?
Models:
class Images(models.Model):
image = models.ImageField(upload_to=update_filename, blank=True, null=True, verbose_name="Obrazek")
gallery = models.ForeignKey('Gallery', blank=True, null=True)
class Gallery(models.Model):
gallery_name = models.CharField(max_length=128)
gallery_description = models.TextField(blank=True, null=True)
View:
def index(request):
p = Gallery.objects.filter(gallery_name="main").order_by('-id')
return TemplateResponse(request, 'gallery.html',
{'gallery': p,
},)
Template:
{% for n in gallery.all %}
<h2 class="center">{{n.gallery_name}}</h2>
<hr>
{% for n in gallery.images_set %}
<div class="grid_4">
{{ n.image }}
</div>
{% endfor%}
Try something along the lines of:
From here you should be able to do things like:
or something similar as needed to pull what you want. The same goes the other way. To pull all images in a gallery you would do
Though the assignments at the end aren’t necessary, I usually just pass gallery.images.all() or image.gallery_set.all() directly. Note the “_set” at the end of the reference from the object that does not contain the M2M definition.
On the subject of direct usage, you can do compound references like
as well, but you have to decide when this makes code more clear and concise and when it just makes it more confusing to read later.
I hope this put you in the right direction.
Update
In your comment below you noticed that you cannot do
This is because you would be trying to filter() or all() on a queryset, not an individual model. So to make this work you can use a for loop in your template. Something like
And then
or something like this. Of course, you need to do whatever formatting steps you want to make this look right, but that’s a way to get at your data.