Уведомления

Группа в Telegram: @pythonsu
  • Начало
  • » Django
  • » Использовать результат запроса из первой функции вьюхи во второй функции этой же вьюхи. [RSS Feed]

#1 Апрель 17, 2013 12:57:38

MikaMika
Зарегистрирован: 2012-11-07
Сообщения: 51
Репутация: +  0  -
Профиль   Отправить e-mail  

Использовать результат запроса из первой функции вьюхи во второй функции этой же вьюхи.

Привет.
Есть шаблон одного из приложений проекта (пусть будет app1).

{% extends 'base.html' %}
{% block content %}
<TABLE>
<TR>
<TD>{% block info1 %}{{ info1 }}{% endblock %}</TD>
<TD>{% block info2 %}{{ info2 }}{% endblock %}</TD>
</TR>
</TABLE>
{% endblock %}
Есть функция вьюхи, которая рендерит этот шаблон, а именно блок “info1”.
Ну например:
def inf1(request):
    info1 = Info1.objects.get(pk=1)
    return render(request, 'app1_base.html', {'info1': info1}
Ещё одна функция этой же вьюхи так же использует этот основной шаблон и рендерит контент в блок “info2”.
Ну например:
def inf2(request):
    info2 = Info2.objects.get(pk=1)
    return render(request, 'app1_base.html', {'info2': info2}
Но к сожалению при работе второй функции вьюхи, блок “info1” остаётся пустым, так - как рендерится в первой функции вьюхи приложения app1.
А мне нужно что бы он (блок “info1”) всегда был заполненный.
Как это сделать?
Я пока нашёл только один выход.
Это сделать одинаковые запросы во второй функции и передать результат в шаблон.
def inf2(request):
    info1 = Info1.objects.get(pk=1)
    info2 = Info2.objects.get(pk=1)
    return render(request, 'app1_base.html', {'info1': info1, 'info2': info2}
Как ещё можно сделать подобную вещь?






Отредактировано MikaMika (Апрель 17, 2013 12:58:59)

Офлайн

#2 Апрель 17, 2013 17:36:39

reclosedev
От: Н.Новгород
Зарегистрирован: 2012-03-29
Сообщения: 870
Репутация: +  173  -
Профиль   Отправить e-mail  

Использовать результат запроса из первой функции вьюхи во второй функции этой же вьюхи.

Офлайн

#3 Апрель 17, 2013 20:54:47

buddha
От:
Зарегистрирован: 2012-03-02
Сообщения: 422
Репутация: +  15  -
Профиль   Отправить e-mail  

Использовать результат запроса из первой функции вьюхи во второй функции этой же вьюхи.

reclosedev
Можно написать свой context processorhttps://docs.djangoproject.com/en/dev/ref/templates/api/#writing-your-own-context-processors

Почему context processor? Я вот недавно столкнулся с подобным, на все страницы надо было одну форму выводить. Пришел к выводу, что этим занимается middleware. Ошибаюсь?

Посему советую создать свой промежуточный слой middleware, в котором будет обрабатываться ответ из каждой фунции и будет добавляться в него info2 = Info2.objects.get(pk=1). Но в таком случае нужно будет заменить все сокращения, типа render, render_to_response на SimpleTemplateResponse\TemplateResponse.
Либо запилить декоратор.
Либо оставить как есть, ведь способы описанные выше по своей сути то же самое.

Офлайн

#4 Апрель 17, 2013 22:02:47

reclosedev
От: Н.Новгород
Зарегистрирован: 2012-03-29
Сообщения: 870
Репутация: +  173  -
Профиль   Отправить e-mail  

Использовать результат запроса из первой функции вьюхи во второй функции этой же вьюхи.

buddha
Не совсем понял, что вы предлагаете (process_view? process_template_response?).
Если ТС нужны данные только в шаблоне, а не во вьюхах, context processor как раз подойдет. Кмк middleware для более низкоуровневых/сложных вещей.

buddha
Но в таком случае нужно будет заменить все сокращения, типа render, render_to_response на SimpleTemplateResponse\TemplateResponse.
Либо запилить декоратор.
Это почему?

Офлайн

#5 Апрель 17, 2013 22:43:50

buddha
От:
Зарегистрирован: 2012-03-02
Сообщения: 422
Репутация: +  15  -
Профиль   Отправить e-mail  

Использовать результат запроса из первой функции вьюхи во второй функции этой же вьюхи.

Да, я имел ввиду process_template_response.

У объекта HttpResponse нету возможности(интерфейса) для добавления в контекст новых переменных(это я про render, render_to_response).

Standard HttpResponse objects are static structures. They are provided with a block of pre-rendered content at time of construction, and while that content can be modified, it isn’t in a form that makes it easy to perform modifications.

However, it can sometimes be beneficial to allow decorators or middleware to modify a response after it has been constructed by the view. For example, you may want to change the template that is used, or put additional data into the context.

TemplateResponse provides a way to do just that. Unlike basic HttpResponse objects, TemplateResponse objects retain the details of the template and context that was provided by the view to compute the response. The final output of the response is not computed until it is needed, later in the response process.
Я так понял, что SimpleTemplateResponse был создан чисто под эти ситуации , да и сам этот класс наследник HttpResponse. А TemplateResponse просто уже включает RequestContext. Проще в исходный код посмотреть…

Отредактировано buddha (Апрель 17, 2013 23:05:13)

Офлайн

#6 Апрель 18, 2013 07:26:22

reclosedev
От: Н.Новгород
Зарегистрирован: 2012-03-29
Сообщения: 870
Репутация: +  173  -
Профиль   Отправить e-mail  

Использовать результат запроса из первой функции вьюхи во второй функции этой же вьюхи.

А, да, шорткаты HttpResponse же возвращают в отличие от generic views.

Получается, если не используется TemplateResponse, то для добавления значения во все шаблоны проще использовать context processor.

Офлайн

#7 Апрель 18, 2013 09:30:54

svas
От:
Зарегистрирован: 2010-01-27
Сообщения: 239
Репутация: +  9  -
Профиль   Отправить e-mail  

Использовать результат запроса из первой функции вьюхи во второй функции этой же вьюхи.

MikaMika
А мне нужно что бы он (блок “info1”) всегда был заполненный.

Я пока нашёл только один выход.
Это сделать одинаковые запросы во второй функции и передать результат в шаблон.
Если блок info1 должен быть заполнен только в inf2 проще просто передавать его в шаблон из inf2.
Если блок info1 должен быть заполнен вообще везде то есть 2 варианта:
1. Как советовали выше написать context processor.
2. Использовать class based views и написать миксин с переопределенным методом get_context_data и наследовать от него все вьюхи.
Первый вариант наверное лучше.



Офлайн

#8 Апрель 19, 2013 12:06:31

MikaMika
Зарегистрирован: 2012-11-07
Сообщения: 51
Репутация: +  0  -
Профиль   Отправить e-mail  

Использовать результат запроса из первой функции вьюхи во второй функции этой же вьюхи.

Сделал прослойку:

def return_info1():
    return info1 = Info1.objects.get(pk=1)
Эту функцию использую везде, где нужно:
def inf1(request):
    return render(request, 'app1_base.html', {'info1': return_info1()}
def inf2(request):
    info2 = Info2.objects.get(pk=1)
    return render(request, 'app1_base.html', {'info1': return_info1(), 'info2': info2}
Насколько я помню запросы в Django кэшируются, и это хорошо!

Отредактировано MikaMika (Апрель 19, 2013 12:06:44)

Офлайн

#9 Апрель 19, 2013 18:44:13

reclosedev
От: Н.Новгород
Зарегистрирован: 2012-03-29
Сообщения: 870
Репутация: +  173  -
Профиль   Отправить e-mail  

Использовать результат запроса из первой функции вьюхи во второй функции этой же вьюхи.

А если еще что-то во все шаблоны нужно будет добавить, будете править все view?

myapp/path/to/context_processor.py

def return_info1(request):
    return {'info1': Info1.objects.get(pk=1)}

settings.py
from django.conf.global_settings import TEMPLATE_CONTEXT_PROCESSORS
 
TEMPLATE_CONTEXT_PROCESSORS += (
    'myapp.path.to.context_processor.return_info1',
)

Офлайн

  • Начало
  • » Django
  • » Использовать результат запроса из первой функции вьюхи во второй функции этой же вьюхи.[RSS Feed]

Board footer

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

Powered by DjangoBB

Lo-Fi Version