【问题标题】:Combining, filtering models/views in a ManyToMany Django在多对多 Django 中组合、过滤模型/视图
【发布时间】:2011-07-11 03:21:36
【问题描述】:

我正在开发一个漫画书数据库,其中包含主要封面和变体封面。我有一个显示所有主要封面的页面,但我也想按出版日期的顺序组合变体封面。这是我的模型的一部分:

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.")

主封面页面的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).select_related(depth=1)
    return render_to_response('comics/covers.html', {'issues': issues}, context_instance=RequestContext(request))

但我也想显示变体封面,而不仅仅是cover_image。有没有办法做到这一点?也许有一些image 然后过滤类别(Image 模型的封面)?

我当然可以这样做:

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))

但这并没有像def covers 那样给我足够的灵活性,我希望它们按pub_date 组合和排序,例如def covers

编辑

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))

模板.html: {% for issue in issues %}{% for image in issue.get_images %}{{ image.image }}{% endfor %}{% endfor %} - 不显示任何内容,但是,{% for issue in issues %} {% for image in issue.get_images %} {{ issue.cover_image }} {% endfor %} {% endfor %}重复显示Issue 模型的cover_image,如果有分类在Image 模型中的变体封面。

我可以做些什么来解决这个问题,以便正确显示所有内容?再次记录一下,我希望它显示{{ cover_image }}(来自Issue 模型)和{{ image.image }} 组合定义的Image 模型。

【问题讨论】:

  • 我是否纠正了您无法访问由covers() 视图呈现的模板中的变体图像的问题?
  • 我想访问变体图像(images = ManyToManyField(Image),类别 = 封面)并将它们与模板的cover_image 组合,以便按pub_date 排序。

标签: django django-models django-views


【解决方案1】:

如果我正确理解您的问题,解决它的一种方法是向Issue 类添加一个方法,如下所示:

class Issue(models.Model):
    # fields...

    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

然后,在您的模板中,您可以执行例如{% for image in issue.get_images %}...

(如果它不是您所需要的——那么,我认为,如果您提供一些模板代码作为您想要实现的目标的示例会更好。)

【讨论】:

  • 喜欢这个? {% for image in issue.get_images %}<li><img src="{% if image.image %}{% thumbnail image.image 94x150 %}{% else %}(thumbnail){% endif %}" alt="{{ issue }}" width="94" height="150"/></li>{% endfor %} 我只是希望合并后的图像能够按照问题模型定义的发布日期排序。
  • 是的,这样您将输出给定问题的所有图像,但是按发布日期对组合图像进行排序是什么意思? Image 模型上没有这样的字段,只有 Issue... 你的意思是图像应该按 date_added 排序吗?
  • 我上面显示的模板标签没有显示任何内容。而且,是的,我有date_added,但我希望我可以通过ManyToMany Image 以某种方式在Issue 模型上连接pub_date。这可能吗?
  • 上面的例子展示了如何获取一个特定问题的图片。你应该在嵌套循环中使用它,就像这样:{% for issue in issues %}{% for image in issue.get_images %}<...>{% endfor %}{% endfor %}。如果您有不同的要求,请用您的模板代码应该是什么样子来更新问题。
  • 嗨,延迟响应。当我这样做时,这几乎可以工作:{% for issue in issues %} {% for image in issue.get_images %} <li>{{ issue.cover_image }} </li> {% endfor %} {% endfor %} 这是正确的,因为它通过 M2M 显示了cover_image 和变体(但如果有变体,它会重复cover_image,当然)。但是,当我执行{{ image.image }} 时,它什么也没有显示。我的模板代码有问题吗?
猜你喜欢
  • 2023-03-18
  • 1970-01-01
  • 2021-11-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-20
  • 2019-09-20
相关资源
最近更新 更多