django фильтрует перегруппировку в forloop - PullRequest
1 голос
/ 24 июля 2011

У меня есть модель под названием 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_list и for item.ict_objects in resource_list и <a href="{{ item.ict_objects.link_address }}">. Если бы это было в поле зрения, я мог бы, вероятно, сделать фильтр только на .filter('is_ict': True), но, учитывая, что он находится внутри замкнутого цикла, я не знаю, где выполнять фильтрацию.

Я также пытался написать regroup whatever.resource_set.filter('is_ict': True) в шаблоне, но синтаксис для перегруппировки, кажется, использует resource_set.all вместо resource_set.all() (и я не знаю почему), поэтому текст фильтра здесь не работает.

1 Ответ

0 голосов
/ 25 июля 2011

Оказалось, что это можно было сделать, используя специальный шаблонный фильтр. Первоначальные попытки фильтрации внутри шаблона не работали, учитывая, что , как хорошо задокументировано , язык шаблонов не является полноценной средой 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). Это единственный способ обратиться к значению True или False?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...