2011-04-25 34 views
0

我想通过类别过滤图像。它有效,但不是我想要的方式。这里是我的模型是如何设置的:试图在Django中按类别过滤图像

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 }} or {{ scan }} 

它返回:

<Image: Astonishing X-Men 1 Cover A>] [<Image: Astonishing X-Men 1, teamshot>] 

显然,我需要它返回图片网址。添加{{cover.url}}不起作用。

哦,我刚刚意识到它没有显示问题中的特定图像。它显示分类为扫描或封面的所有图像。

回答

0

在你现在的代码,你就返回所有的图像,即使是AREN的那些”与您选择的漫画问题相关联。我假设你想要的选择问题。你可能想这样做,而不是:

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> 
+0

这工作,很好。非常感谢。我遇到的唯一问题 - 有时,有多个封面和多个扫描 - 绝对不止一个扫描。在这些意见中我会怎么做呢?我将[0]移除给他们,但是这只是没有任何显示。 – AAA 2011-04-25 22:41:27

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 %} 
+0

它显示为 '惊人的X战警1套A' 了,但我把它_need_到显示图像的URL,而不是文本,以便我可以将它放入HTML中。谢谢。同样,添加{{cover.url}}不起作用。 – AAA 2011-04-25 21:50:51

+0

好的,我为模板添加了一个示例,希望有所帮助! – 2011-04-25 22:32:35

+0

修好了,现在,欢呼声 – 2011-04-25 22:43:23