Уведомления

Группа в Telegram: @pythonsu
  • Начало
  • » Django
  • » Три выборки из модели в одном шаблоне [RSS Feed]

#1 Авг. 14, 2014 14:04:25

iceberg
Зарегистрирован: 2014-08-09
Сообщения: 8
Репутация: +  0  -
Профиль   Отправить e-mail  

Три выборки из модели в одном шаблоне

День добрый! Хотел поинтересоваться у гуру Django насчёт оптимального решения. Есть одна несложная модель

class AlarmA(models.Model):
    user = models.ForeignKey(User)
    caption = models.CharField(max_length=30)
    alarmdate = models.DateField('Alarm date', blank=True, null=True)
    # other fields

Для каждого пользователя делается выборка, состоящая из всех его личных экземпляров модели (по полю User). Это делается элементарно, но есть одна проблема. В шаблоне нужно выводить список не в одном месте, а в трех, в зависимости от значения поля alarmdate, т.е. фактически разбить весь большоя список на три подсписка (3 группы).
1. Записи с заполненным значением alarmdate, где alarmdate меньше текущей даты.
2. Записи с заполненным значением alarmdate, где alarmdate равны или больше текущей даты.
3. Записи с незаполненным значением alarmdate.

Как я понимаю, при рендеринге нет возможности сравнивать даты с помощью существующих шаблонных фильтров и тегов.

Для себя нашёл два варианта решения.

1. Вьюха, произведенная от LstView возвращает список с одной из групп alarmdate (например, только не заполненные). Два других подсписка передаются в рендеринг через дополнительные контекст с помощью get_context_data. В этом случае имеем по сути три выборки во вью, но при обработке контекста каждый подсписок обрабатывается автономно от других.

2. Вьюха возвращает один общий список, но у каждого экземаляра в большом общем списке ставим маркер группы (например с помощью дополнительного поля и метода extra). В этом случае придётся в шаблоне трижды проходить один и тот же цикл, со своим условеым оператором для каждой секции шаблона.

Вопрос такой: какой из этих двух вариантов решения является оптимальным с точки зрения наименьшей нагрузки на сервер? Не знаю, имеет ли значение тип, если что у меня nginx+gunicorn+postgresql? И вообще, может быть напрасно парюсь, а есть решение лучше?

Офлайн

#2 Авг. 14, 2014 20:44:02

Alen
Зарегистрирован: 2013-08-01
Сообщения: 373
Репутация: +  49  -
Профиль   Отправить e-mail  

Три выборки из модели в одном шаблоне

iceberg
Как я понимаю, при рендеринге нет возможности сравнивать даты с помощью существующих шаблонных фильтров и тегов.

Почему? А unixtime.

Офлайн

#3 Авг. 14, 2014 21:41:27

iceberg
Зарегистрирован: 2014-08-09
Сообщения: 8
Репутация: +  0  -
Профиль   Отправить e-mail  

Три выборки из модели в одном шаблоне

Alen
Почему? А unixtime.
В шаблоне? Типа сравнить c now? Ну не знаю, что-то никогда не встречал.

В любом случае остается вопрос, что выгоднее: три выборки во вьюхе и три меньших цикла в шаблоне или три цикла в шаблоне по всему здоровому списку каждый?

Офлайн

#4 Авг. 14, 2014 22:00:36

Singularity
Зарегистрирован: 2011-07-28
Сообщения: 1387
Репутация: +  75  -
Профиль   Отправить e-mail  

Три выборки из модели в одном шаблоне

iceberg
выбрать все и отсортировать вручную в память не влезет?

Напиши оба варианта и сравни.

Офлайн

#5 Авг. 15, 2014 06:34:01

ilnur
От: Казань
Зарегистрирован: 2009-01-06
Сообщения: 524
Репутация: +  22  -
Профиль   Отправить e-mail  

Три выборки из модели в одном шаблоне

я бы делал по 1 варианту. потому что вся логика должна быть во вьюхе, а шаблон должен просто рендерить стрницу, без никакой логики.

Офлайн

#6 Авг. 15, 2014 09:56:59

FishHook
От:
Зарегистрирован: 2011-01-08
Сообщения: 8312
Репутация: +  568  -
Профиль   Отправить e-mail  

Три выборки из модели в одном шаблоне

ilnur
без никакой логики.
Это красиво в теории, но не работает на практике.
Пример: есть страница на сайте, которая отображает объём продаж носков по месяцам.
Таблица в БД простая:
product: ForeignKey(Product)
year: Integer
month: Integer
value: Integer
Страница состоит из таблицы, содержащей из 12 столбцов и одну строку. Какие данные должны быть помещены в контекст?
Наверное, какие-то такие:
context["month_data"] = TotalSales.objects.filter(year=2014, product__name="Sock").order_by("month")
Для того, чтобы нарисовать требуемую таблицу данных достаточно - тупо for.
<table>
<tr>
{% for val in  month_data%}
    <td>{{ val }}</td>
{% endfor %}
</tr>
Вы это сделали, получили гонорар, заказчика всё устраивает. Но через месяц он звонит и говорит: Ильнур, хочу чтобы в каждой ячейке была информация о том, на сколько возросли продажи относительно предыдущего месяца. Ваши действия?
Вариант первый (тот который предполагает Ваш подход): Вы во View вместо простого запроса к БД конструируете нечто такое:
qs = TotalSales.objects.filter(year=2014, product__name="Sock").order_by("month")
res = []
for i, t in enumerate(qs):
    value = t.value
    if i = 0:
         previous = 0
    else:
         previous = res[ i - 1 ]
    increment = (value - previous) if previous else 0   
context["month_data"] = {"value": vaue, "increment": increment}
Соответственно, шаблон Вам тоже нужно переписать.

Вариант второй, представление мы не трогаем, контекст остался тот же самый.
<table>
<tr>
{% for val in  month_data %}
    {% if forloop.counter > 0 %}
        <td>{{ val - month_data[forloop.counter - 1] }}</td>
    {% else %}
        <td>0</td>
    {% endif %}
    <td>{{ val }}</td>
{% endfor %}
</tr>
Что проще и логичней? Да-да-да, я знаю, что в шаблонах Джанги нельзя просто так взять и вычесть одно значение из другого, Джанга рассчитана на верстальщиков, не имеющих понятия об элементарной арифметике. Но Вы то имеете такое понятие, Вам то нахрена подобные извраты? А завтра заказчик опять поменяет ТЗ, скажет “А давай еще сумму по месяцам”, а потом “А давай средний прирост”, “А давай собачий член сбоку нарисуем” …
И каждый раз Вы будете переписывать представление? А зачем? Как с самого начала было достаточно данных для построения страницы, так их по прежнему достаточно.

ilnur
без никакой логики.
Это такая вещь в себе, на которую молятся, которой пытаются безусловно следовать, НО ЗАЧЕМ? Вот не станет мой проект лучше, быстрее и расширяемей, если я выпилю всю логику из шаблонов, ни на капельку не станет. Но геморроя, лично мне, прибавит.

Поэтому jinja2 only.



Отредактировано FishHook (Авг. 15, 2014 10:00:42)

Офлайн

#7 Авг. 15, 2014 15:47:00

ilnur
От: Казань
Зарегистрирован: 2009-01-06
Сообщения: 524
Репутация: +  22  -
Профиль   Отправить e-mail  

Три выборки из модели в одном шаблоне

FishHook
полностью с вами согласен. но в данном случаем, я бы сделал так, как я написал.

FishHook
Поэтому jinja2 only.
тогда давайте сразо на мако писать и шаблоны и вьюхи. :)
насколько я знаю, в мако в темплайты сразу можно писать питон код

:)

Отредактировано ilnur (Авг. 15, 2014 15:47:15)

Офлайн

#8 Авг. 15, 2014 17:09:56

FishHook
От:
Зарегистрирован: 2011-01-08
Сообщения: 8312
Репутация: +  568  -
Профиль   Отправить e-mail  

Три выборки из модели в одном шаблоне

То есть у Вас дихотомия мозга: или следуем заветам MVC до усёра, или кодим в шаблоне на питоне.
Ильнур, так нельзя. Разумных людей отличает способность выбирать инструмент для задачи, взвешивая “pro” и “contra”.



Отредактировано FishHook (Авг. 15, 2014 19:51:09)

Офлайн

#9 Авг. 15, 2014 17:35:53

ilnur
От: Казань
Зарегистрирован: 2009-01-06
Сообщения: 524
Репутация: +  22  -
Профиль   Отправить e-mail  

Три выборки из модели в одном шаблоне

придерживаемся мвс, где он мешает или не подходит, пишет по своему

Офлайн

#10 Авг. 15, 2014 18:06:55

FishHook
От:
Зарегистрирован: 2011-01-08
Сообщения: 8312
Репутация: +  568  -
Профиль   Отправить e-mail  

Три выборки из модели в одном шаблоне

ilnur
где он мешает или не подходит, пишет по своему
А людей учите почему то иному
а шаблон должен просто рендерить стрницу, без никакой логики.
категоричненько так.



Офлайн

  • Начало
  • » Django
  • » Три выборки из модели в одном шаблоне[RSS Feed]

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version