Note that there are some explanatory texts on larger screens.

plurals
  1. POCombining, filtering models/views in a ManyToMany Django
    primarykey
    data
    text
    <p>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:</p> <pre><code>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.") </code></pre> <p>My views.py for the main cover page looks like this: </p> <pre><code>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)) </code></pre> <p>But I would like to display the variant covers too and not just the <code>cover_image</code>. Is there a way to do this? Maybe with something <code>image</code> and then filtering the category (of the <code>Image</code> model by cover)? </p> <p>I, of course, can do this:</p> <pre><code>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)) </code></pre> <p>But that does not give me enough flexibility as <code>def covers</code> does, and I want them combined and sorted by pub_date, like <code>def covers</code>.</p> <p><strong>Edit</strong></p> <p>models.py:</p> <pre><code>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 </code></pre> <p>views.py:</p> <pre><code>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)) </code></pre> <p>template.html: <code>{% for issue in issues %}{% for image in issue.get_images %}{{ image.image }}{% endfor %}{% endfor %}</code> - displays nothing, however, <code>{% for issue in issues %} {% for image in issue.get_images %} {{ issue.cover_image }} {% endfor %} {% endfor %}</code> will <strong>repeatedly</strong> display the <code>cover_image</code> of the <code>Issue</code> model if there are variant covers, which are categorized in the <code>Image</code> model. </p> <p>What can I do to fix this, so that it shows everything correctly? And for the record again, I want it to display the <code>{{ cover_image }}</code> (from the <code>Issue</code> model) and the <code>{{ image.image }}</code> as defined by the <code>Image</code> model combined.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload