Reputation: 2315
Using Django 1.8. I am building app that has photo galleries with photos that belong to those galleries (my galleries are called 'fountains')
My photo model includes a 'gallery' field (boolean true or false) that designates a photo as the 'main fountain photo. Only one photo has this gallery field = True at any given time.
Trying to figure out how to get a query (queries) in a 'gallery home page' that will have list of all fountains with one photo for each fountain. My presentation will be a responsive grid of fountain name plus the single photo.
I am struggling with the view to send the fountain info plus the info about the single photo.
My models:
class Fountains(models.Model):
name = models.CharField(max_length=100, blank=True, null=True)
description = models.TextField(blank=True, null=True)
street_address = models.CharField(max_length = 100, blank=True, null=True)
street_number = models.CharField(max_length = 20, blank=True, null=True)
city = models.CharField(max_length=100, blank=True, null=True)
lat = models.CharField(max_length=20, blank=True, null=True)
lon = models.CharField(max_length=20, blank=True, null=True)
created = models.DateTimeField(auto_now_add=True)
#slug = models.SlugField(prepopulate_from=("name",))
modified = models.DateTimeField(auto_now=True)
#tags = TaggableManager()
#def __unicode__(self):
# return self.name.name
class Meta:
managed = True
db_table = 'fountains'
#verbose_name_plural = 'Fountains'
class Photos(models.Model):
#filename = models.CharField(max_length=100)
filename = models.ImageField(upload_to='.')
ext = models.CharField(max_length=5, blank=True, null=True)
desc = models.TextField(blank=True, null=True)
#fountain_id = models.IntegerField(blank=True, null=True)
fountain = models.ForeignKey(Fountains)
user_id = models.IntegerField(blank=True, null=True)
tag_count = models.IntegerField(blank=True, null=True)
photos_tag_count = models.IntegerField(blank=True, null=True)
comment_count = models.IntegerField(blank=True, null=True)
gallery = models.NullBooleanField(blank=True)
created = models.DateTimeField(auto_now_add=True)
modified = models.DateTimeField(auto_now=True)
#def __unicode__(self):
# return self.filename.name
class Meta:
managed = True
db_table = 'photos'
#verbose_name_plural = 'Photos'
My view for the home page:
def home(request):
"""Renders the home page."""
assert isinstance(request, HttpRequest)
#fountain_list = Fountains.objects.order_by('name')
fountain_list = Fountains.objects.filter(photos__gallery=True).order_by('name')
context_dict = { 'fountain_list': fountain_list }
return render(
request,
'app/index.html',
context_dict,
context_instance = RequestContext(request)
)
My template for the home page view:
{% extends "app/layout.html" %}
{% block content %}
<div class="col-sm-10">
{% for fountain in fountain_list %}
<div style="float:left; class="img-responsive">
<a href="/photos/{{ fountain.id }}/"}>{{ fountain.name }}</a>
{% for photo in fountain.photos_set.all %}
<img src="{{ MEDIA_URL }}{{ photo.filename }}" alt="{{ photo.filename }}" class="thumbnail" width="100" height="100" style="border:none;"/>
</a>
{% endfor %}
</div>
{% endfor%}
</div>
{% endblock %}
I have another similar view where i am getting the count of photos for each fountain using this:
fountain_list = Fountains.objects.annotate(photo_count=Count('photos')).order_by('name')
The fact that this notation can count photos for each fountain suggests that it can also get a specific photo as well. So i my view tries using 'aggregate' instead of 'annotate':
fountain_list = Fountains.objects.filter(photos__gallery=True).order_by('name')
However this just reduced the number of fountains in the object to those that had the gallery field = True.
Still, it seems that that the photo with gallery field = true might be contained in this object. But i couldn't retrieve it.
I have tried to get the 'gallery = true' photo in the template. I posited that as it was coming from the filtered fountain_list object, that 'all' would just be one single photo. So tried this in the template:
{% for photo in fountain.photos_set.all %}
But it retrieves all photos for all fountains.
I found a few other vaguely similar examples elsewhere via search but they al had sufficiently different notation (eg 'object_set' didn't work for me) that didn't help me.
I am looking for way to get the one related photo record with gallery = True into my view and template so that I can show one photo for each fountain.
My presentation will be a responsive grid of fountain name plus the single photo. Thanks!
EDIT to show new view and template based on accepted answer below:
My updated view:
def home(request):
"""Renders the home page."""
assert isinstance(request, HttpRequest)
photo_list = Photos.objects.filter(gallery=True)
context_dict = { 'photo_list': photo_list }
return render(
request,
'app/index.html',
context_dict,
context_instance = RequestContext(request)
)
My updated template:
{% extends "app/layout.html" %}
{% block content %}
<div class="col-sm-10">
{% for photo in photo_list %}
<div style="float:left; class="img-responsive">
<a href="/photos/{{ photo.fountain.id }}/"}>{{ photo.fountain.name }}</a>
<img src="{{ MEDIA_URL }}{{ photo.filename }}" alt="{{ photo.filename }}" class="thumbnail" width="100" height="100" style="border:none;"/>
</a>
</div>
{% endfor%}
</div>
{% endblock %}
Upvotes: 0
Views: 152
Reputation: 911
def home(request):
context = {}
context['photos'] = Photo.objects.first()
return render (request, 'html', context)
or
photo = Photo.objects.first()
return render(request, 'html', {'photo':photo})
html
<p>{{ photo.fanat.name }}</p>
<img src="{{ photo.image.url }}">
Upvotes: 2