I’m working on a comic book database and there are main covers and variant covers. I have a page that shows all the Main covers, but I’d like to combine the variant covers too, in order of the publication date. This is what part of my models look like:
class Image(models.Model):
CATEGORY_CHOICES = (
('Cover', 'Cover'),
('Scan', 'Scan'),
('Other', 'Other'),
)
title = models.CharField(max_length=128)
number = models.CharField(max_length=20, help_text="Do not include the '#'.")
image = models.ImageField(upload_to="images/")
category = models.CharField(max_length=10, choices=CATEGORY_CHOICES)
### The variant cover is determined by the category_choice 'Cover'. ###
contributor = models.ManyToManyField(Contributor, blank=True, null=True)
date_added = models.DateField(auto_now_add=True, auto_now=True)
def __unicode__(self):
return self.title
class Meta:
ordering = ['title']
class Issue(models.Model):
CATEGORY_CHOICES = (
('Major', 'Major'),
('Minor', 'Minor'),
('Cameo', 'Cameo'),
('Other', 'Other'),
)
title = models.ForeignKey(Title)
number = models.CharField(max_length=20, help_text="Do not include the '#'.")
pub_date = models.DateField(blank=True, null=True)
cover_image = models.ImageField(upload_to="covers/", blank=True, null=True)
### This would be where the main image goes. ^^^ ###
images = models.ManyToManyField(Image, related_name="images_inc", blank=True, null=True)
### This is where the variant covers go.^^^ ###
has_emma = models.BooleanField(help_text="Check if Emma appears on the cover.")
My views.py for the main cover page looks like this:
def covers(request):
sort_by = request.GET.get('sort', 'pub_date')
if sort_by not in ['-date_added', 'date_added', '-pub_date', 'pub_date']:
sort_by = '-date_added'
issues = Issue.objects.filter(has_emma=True).order_by(sort_by).select_related(depth=1)
return render_to_response('comics/covers.html', {'issues': issues}, context_instance=RequestContext(request))
But I would like to display the variant covers too and not just the cover_image. Is there a way to do this? Maybe with something image and then filtering the category (of the Image model by cover)?
I, of course, can do this:
def variants(request):
Issue.objects.filter(has_emma=True).order_by(sort_by).select_related(depth=1)
images = Image.objects.filter(category='Cover').order_by('id')
return render_to_response('comics/variants.html', {'images': images}, context_instance=RequestContext(request))
But that does not give me enough flexibility as def covers does, and I want them combined and sorted by pub_date, like def covers.
Edit
models.py:
class Image(models.Model):
CATEGORY_CHOICES = (
('Cover', 'Cover'),
('Scan', 'Scan'),
('Other', 'Other'),
)
title = models.CharField(max_length=128)
image = models.ImageField(upload_to="images/")
category = models.CharField(max_length=10, choices=CATEGORY_CHOICES)
date_added = models.DateField(auto_now_add=True, auto_now=True)
def __unicode__(self):
return self.title
class Meta:
ordering = ['title']
class Issue(models.Model):
title = models.ForeignKey(Title)
number = models.CharField(max_length=20)
######
has_emma = models.BooleanField(help_text="Check if cover appearance.")
cover_image = models.ImageField(upload_to="covers/", blank=True, null=True)
images = models.ManyToManyField(Image, related_name="images_inc", blank=True, null=True)
######
def get_images(self):
''' Returns a list of all cover images combined,
"main" cover image first.
'''
images = [self.cover_image]
for image in self.images.filter(category='Cover'):
images.append(image.image)
return images
views.py:
def covers(request):
sort_by = request.GET.get('sort', '-pub_date')
if sort_by not in ['-date_added', 'date_added', '-pub_date', 'pub_date']:
sort_by = '-date_added'
issues = Issue.objects.filter(has_emma=True).order_by(sort_by)
return render_to_response('template.html', {'issues': issues,}, context_instance=RequestContext(request))
template.html:
{% for issue in issues %}{% for image in issue.get_images %}{{ image.image }}{% endfor %}{% endfor %} – displays nothing, however, {% for issue in issues %} {% for image in issue.get_images %} {{ issue.cover_image }} {% endfor %} {% endfor %} will repeatedly display the cover_image of the Issue model if there are variant covers, which are categorized in the Image model.
What can I do to fix this, so that it shows everything correctly? And for the record again, I want it to display the {{ cover_image }} (from the Issue model) and the {{ image.image }} as defined by the Image model combined.
If I understand your problem correctly, one way to solve it would be adding a method to
Issueclass like this:Then, in your template, you can do, for example,
{% for image in issue.get_images %}....(If it’s not exactly what you need—then, I think, it would be better if you provide some template code as an example of what you’re trying to achieve.)