суббота, 25 февраля 2012 г.

Опрос (ч.3.2)

В части 3.1 мы исследовали возможности админки Django. В этой части мы продолжим наши исследования.



1. Опросов может быть много, поэтому мы хотим отслеживать популярные из них. В админке Django нужно видеть, в каких опросах проголосовало более 100 человек. Таким образом, в админке наряду с полями Вопрос, Дата публикации, Опубликован должно появиться поле Популярный.
Обратите внимание, что количество голосов, при котором пост становится популярным, может измениться в будущем. Следовательно, этот параметр разумно вынести в настройки. Поскольку эта настройка специфична для приложения polls, то разместим ее в нем. Создадим файл polls/settings.py:
# -*- coding: utf-8 -*-

# Кол-во голосов, при котором пост в админке становится Популярным
POLLS_POPULAR_VOTES_LIMIT = 100

2. Используем эти настройки в файле моделей нашего приложения polls/models.py:
# ...
# Импортируем настройки приложения polls
import settings

class Question(models.Model):
    # ...
    # Этот метод позволяет выявить Популярный опрос для показа в админке
    def is_popular(self):
        answers = Answer.objects.filter(question_id=self.id)
        votes_total = sum([answer.votes for answer in answers])
        return votes_total > settings.POLLS_POPULAR_VOTES_LIMIT
    # Описание столбца в админке
    is_popular.short_description = 'Популярный'

3. Чтобы колонка Популярный появилась в админке, нужно отредактировать файл polls/admin.py:

class QuestionAdmin(admin.ModelAdmin):
    # ...
    # Добавим название метода модели is_popular()
    list_display = ('title', 'date_published', 'is_active', 'is_popular')

В результате в админке появится новая колонка Популярный:


4. Согласитесь, названия True, False не очень презентабельны. Давайте их заменим на изображения, подобные тем, что находится в колонке Опубликован. Для этого метод is_popular() должен возвращать html изображения. При этом картинок у нас будет две, путь к ним мы укажем в настройках приложения - polls/settings.py:
# ...

IMG_TRUE_PATH = '/static/admin/img/icon-yes.gif'
IMG_FALSE_PATH = '/static/admin/img/icon-no.gif'

5. Чтобы метод is_popular() возвращал html, отредактируем файл polls/model.py:
# ...

class Question(models.Model):
    # ...

    def is_popular(self):
        answers = Answer.objects.filter(question_id=self.id)
        votes_total = sum([answer.votes for answer in answers])
        if votes_total > settings.POLLS_POPULAR_VOTES_LIMIT:
            img_path = settings.IMG_TRUE_PATH
        else:
            img_path = settings.IMG_FALSE_PATH
        return '<img alt="" src="{}" />'.format(img_path)

    is_popular.short_description = 'Популярный'
    # Важно указать эту настройку, чтобы django не экранировал тэги
    is_popular.allow_tags = True

Обратите внимание, мы укзали настройку is_popular.allow_tags = True. Она позволяет нам избежать экранирования и вывести html теги прямо из модели:


6. Искушенный любитель Django (кто постоянно читает документацию) заметит, что шаги 4, 5 можно было заменить одной строчкой кода. Оказывается, для метода есть настройка, которая позволяет True/False заменять на изображения автоматически. Для этого нужно в polls/models.py добавить сточку:

class Question(models.Model):
    # ...

    def is_popular(self):
        answers = Answer.objects.filter(question_id=self.id)
        votes_total = sum([answer.votes for answer in answers])
        return votes_total > settings.POLLS_POPULAR_VOTES_LIMIT

    is_popular.short_description = 'Популярный'
    # Вот настройка, заменяющая False/True на иконки в админке
    is_popular.boolean = True

7. Пусть нам нужно в админке добавить фильтр по дате. Добавьте строчку в polls/admin.py:
# ...
class QuestionAdmin(admin.ModelAdmin):
    # ...
    list_filter = ['date_published']

Тогда в админке справа появится фильтр по дате публикации:


8. Когда опросов много, удобно если есть возможность поиска. Добавим форму поиска по формулировкам вопросов. Добавьте строчку в polls/admin.py:
# ...
class QuestionAdmin(admin.ModelAdmin):
    # ...
    search_fields = ['title']



9. Добавим в админку иерархию по дате: год, месяц… Добавьте строчку в polls/admin.py:
# ...
class QuestionAdmin(admin.ModelAdmin):
    # ...
    date_hierarchy = ['date_published']

При использовании этой настройки вы можете столкнуться с ошибкой:
ImproperlyConfigured at /admin/polls/question/
This query requires pytz, but it isn't installed.
Для устранения этой ошибки нужно установить питоновский пакет pytz (PYthon TimeZone). Если пакет установлен, вы получите такой результат:


Продолжение - Опрос (ч.4)
 

Комментариев нет:

Отправить комментарий