django过滤for循环中的一个组

时间:2011-07-24 12:23:30

标签: django filter for-loop

我有一个名为Subtopic的模型。我的一个模板在一个对象上运行一个forloop,为一个表行的每个单元格返回一个不同的字段。

其中两个表格单元格查找一个字段,该字段是ManytoMany外键,对于同一个外部模型Resource。我希望每个都根据资源模型中的布尔字段的值显示不同的结果。

您在下面看到的内容目前正常,但不会尝试按布尔字段进行过滤。

models.py:

class ICTResourceManager(models.Manager):
    def get_query_set(self):
        return super(ICTResourceManager, self).get_query_set().filter('is_ict': True)

class NonICTResourceManager(models.Manager):
    def get_query_set(self):
        return super(NonICTResourceManager, self).get_query_set().filter('is_ict': False)

class Resource(models.Model):
    subtopics = models.ManyToManyField(Subtopic)
    external_site = models.ForeignKey(ExternalSite)
    link_address = models.URLField(max_length=200, unique=True, verify_exists=False)
    requires_login = models.BooleanField()
    is_ict = models.BooleanField()
    flags = models.ManyToManyField(Flag, blank=True)
    comment = models.TextField()
    def __unicode__(self):
        return u'%s %s' % (self.external_site, self.link_address)
    objects = models.Manager()
    ict_objects = ICTResourceManager()
    nonict_objects = NonICTResourceManager()

    class Meta:
        ordering = ['external_site', 'link_address']

views.py:

def view_ks5topic(request, modulecode, topicshortname):
    listofsubtopics = Subtopic.objects.filter(topic__module__code__iexact = modulecode, topic__shortname__iexact = topicshortname)
    themodule = Module.objects.get(code__iexact = modulecode)
    thetopic = Topic.objects.get(module__code__iexact = modulecode, shortname__iexact = topicshortname)
    return render_to_response('topic_page.html', locals())

我的模板:

        {% for whatever in listofsubtopics %}
        <tr>
            <td>
                {{ whatever.objective_html|safe }}
                <p>
                {% if request.user.is_authenticated %}
                    {% with 'objective' as column %}
                    {% include "edit_text.html" %}
                    {% endwith %}
                {% else %}
                {% endif %}
            </td>
            <td>
                {% regroup whatever.resource_set.all by external_site.name as resource_list %}
                {% for external_site in resource_list %}
                    <h4>{{ external_site.grouper }}</h4>
                    <ul>
                        {% for item in external_site.list %}
                        <li><a href="{{ item.link_address }}">{{ item.comment }}</a></li>
                        {% endfor %}
                    </ul>
                {% endfor %}
            </td>
        </tr>        
        {% endfor %}

正如你所看到的,我已经为模型添加了额外的管理器来为我做过滤,但是当我替换模板中的相应行时,我只是得到了空白。我尝试过:for external_site.ict_objects in resource_listfor item.ict_objects in resource_list以及<a href="{{ item.ict_objects.link_address }}">。如果在视图中我可能只用.filter('is_ict': True)进行过滤,但是在forloop中我不知道在哪里进行过滤。

我还尝试在模板中编写regroup whatever.resource_set.filter('is_ict': True),但重新组合的语法似乎使用resource_set.all而不是resource_set.all()(我不知道为什么)所以滤镜文本没有在这里工作。

1 个答案:

答案 0 :(得分:0)

原来可以使用自定义模板过滤器来完成。考虑到as is well documented模板语言不是一个完全成熟的python环境,在模板中过滤的原始努力是行不通的。对于任何知道替代方法的人来说,我原来的问题仍然是开放的,这种方法可以更直接地解决我最初提出的问题,但这是我如何做到的:

myapp_extras.py:

from django import template

register = template.Library()

def ict(value, arg):
    "filters on whether the is_ict Boolean is true"
    return value.filter(is_ict=arg)

register.filter('ict', ict)

我的模板,请注意第2行中使用自定义过滤器:

<td>
    {% regroup whatever.resource_set.all|ict:1 by external_site.name as resource_list %}
    {% for external_site in resource_list %}
        <h4>{{ external_site.grouper }}</h4>
        <ul>
        {% for item in external_site.list %}
            <li><a href="{{ item.link_address }}">{{ item.comment }}</a></li>
        {% endfor %}
        </ul>
    {% endfor %}
</td>

在此之后,我能够从模型中删除其他自定义管理器。

另外一个问题是,当过滤布尔值is_ict字段时,我发现我必须使用filter(is_ict=1)filter(is_ict=0)。这是引用TrueFalse值的唯一方法吗?