我正在尝试通过类别过滤图像。它工作但不是我想要的方式。以下是我的模型设置方式:
class Image(models.Model):
CATEGORY_CHOICES = (
('Cover', 'Cover'),
('Scan', 'Scan'),
('Other', 'Other'),
)
title = models.CharField(max_length=256)
image = models.ImageField(upload_to="images/")
category = models.CharField(max_length=10, choices=CATEGORY_CHOICES)
contributor = models.ManyToManyField(Contributor, blank=True, null=True)
date_added = models.DateField(auto_now_add=True)
def __unicode__(self):
return self.title
class Meta:
ordering = ['title']
class Issue(models.Model):
...
images = models.ManyToManyField(Image, related_name="images_inc", blank=True, null=True)
....
def __unicode__(self):
return u'%s #%s' % (self.title, self.number)
def get_absolute_url(self):
return "/issues/%s" % self.slug
class Meta:
ordering = ['-date_added']
Views.py:
def issue(request, issue_slug):
issue = get_object_or_404(Issue, slug=issue_slug)
cover = Image.objects.filter(category='Cover')
scan = Image.objects.filter(category='Scan')
return render_to_response('comics/issue_detail.html', {'issue': issue, 'cover': cover, 'scan': scan}, context_instance=RequestContext(request))
我正试图通过Cover或Scan过滤它,如你所见,但是当我把它放入我的模板时:
{{ cover }} or {{ scan }}
它返回:
<Image: Astonishing X-Men 1 Cover A>] [<Image: Astonishing X-Men 1, teamshot>]
显然,我需要它来返回图片网址。添加{{cover.url}}不起作用。
哦,我刚刚意识到它没有显示问题中的特定图像。它显示分类为扫描或封面的所有图像。
答案 0 :(得分:0)
filter总是返回数组中的匹配列表。
如果你只是想要第一场比赛,你可以做这样的事情
cover = issue.images.filter(category='Cover')[:1][0]
scan = issue.images.filter(category='Scan')[:1][0]
但如果没有匹配则会抛出异常,所以最好在尝试中包装但不包括
try:
cover = issue.images.filter(category='Cover')[:1][0]
except:
cover = None
在模板中,由于封面和扫描代表图像对象,因此您可以使用以下语法获取网址:
{{ cover.image.url }} or {{ scan.image.url }}
如果要查看所有图像,可以选择加载封面和扫描(复数)并检查模板中是否为空。除了这里的索引错误之外没有必要,而且它更简单。
在这种情况下,你会这样做:
covers = issue.images.filter((category='Cover'))
然后在模板中:
{% if covers %}
{% for cover in covers %}
{{cover.image.url}} - {{cover.title}}
{% endfor %}
{% endif %}
答案 1 :(得分:0)
在您当前的代码中,您将返回所有图像,甚至是与您选择的漫画问题无关的图像。我假设您想要选定问题的那些。你可能想要这样做:
def issue(request, issue_slug):
issue = get_object_or_404(Issue, slug=issue_slug)
try:
cover = issue.images_inc.filter(category='Cover')[0]
except IndexError:
cover = None
try:
scan = issue.images_inc.filter(category='Scan')[0]
except IndexError:
scan = None
return render_to_response('comics/issue_detail.html', {'issue': issue, 'cover': cover, 'scan': scan}, context_instance=RequestContext(request))
然后,在模板中:
{% if cover.image %}
<img src="{{ cover.image.url }}" alt="{{ cover.image.title }}" />
{% endif %}
{% if scan.image %}
<img src="{{ scan.image.url }}" alt="{{ scan.image.title }}" />
{% endif %}
如果您确实需要多个封面或扫描,那么您不希望只获得第一个项目。实际上,您应该将此逻辑移至models.py
以避免可能的代码重复。
这样的事情会更好:
# models.py
class Issue(models.Model):
...
def scans(self):
return self.images.filter(category='Scan')
def covers(self):
return self.images.filter(category='Cover')
# views.py
def issue(request, issue_slug):
issue = get_object_or_404(Issue, slug=issue_slug)
return render_to_response('comics/issue_detail.html', {'issue': issue }, context_instance=RequestContext(request))
然后,在模板中:
<ul>
{% for cover in issue.covers %}
<li><img src="{{ cover.image.url }}" alt="{{ cover.image.title }}" /></li>
{% empty %}
<li>No cover</li>
{% endfor %}
</ul>
<ul>
{% for scan in issue.scans %}
<li><img src="{{ scan.image.url }}" alt="{{ scan.image.title }}" /></li>
{% empty %}
<li>No scans</li>
{% endfor %}
</ul>