@vfvnvsyevsky

Как в Django передать данные из модели в шаблон в обход views?

Допустим:
Есть main.html и там есть верхняя панель навигации (которая используется со всеми наследующими шаблонами main.html) где высвечивается имя залогиненного юзера.
И есть article.html наследующий main.html.
def article рендерит и передает переменные в article.html
И чтобы в main.html появилось имя пользователя надо его каждый раз передавать через def article:
def article:
    user = request.user.username
    return render_to_response('article.html', user)

Как это упростить до того, чтобы в main.html по умолчанию передавались данные пользователя без явной передачи каждый раз во views?
  • Вопрос задан
  • 8028 просмотров
Решения вопроса 2
@hsc
full stack python back-end developer
Для начала: https://www.python.org/dev/peps/pep-0020/
Один из пунктов там "явное лучше неявного".

Views в django на то и придуманы чтобы передавать данные и делать это явно, но то, как это сделать всецело зависит от Вас. Вы правы, нет смысла во всех вьюхах городить огород с передачей одних и тех же данных, тем более, если они общие для большинства шаблонов, но ни custom context processor, ни тем более custom template tag Вас не выручат так, как может одна простая конструкция:

где-нибудь в utils.py
def base_context(request):
    return Context({
        'user': request.user,
        '...': '...',
    })


Где-нибудь в views.py:
def view(request):
    context = base_context(request)
    context['this view specific data'] = 'happy coding'
    return render_to_response('template.html', context)


Таким образом Вы:
1. Не захламляете общий request flow и сохраняете контроль над контекстом любой вьюхи. Context processors будут вызваны для любого рендера, тогда как такой подход позволит Вам всегда иметь минимум необходимых данных под рукой и полный контроль над всеми вьюхами.

2. Передаете в контекст шаблонизатора только, что действительно должно в него попасть. Больше того, в отдельных вьюхах Вы даже можете переопределить базовые параметры, что не так удобно делать с context processors. (но лучше см. п.3)

3. Можете расширить абстракцию как угодно, и создать хоть 2, хоть 3, хоть больше базовых контекстов под всевозожные ситуации (зависит от архитектуры).
Ответ написан
Комментировать
un1t
@un1t
Убедитесь что у вас реквест есть в контекст процессорах

TEMPLATE_CONTEXT_PROCESSORS = (
  ...
  'django.core.context_processors.request',
)

И тогда можете прямо в шаблонах писать
{{ request.user.username }}

Если другие данные нужны, то в общем случае надо написать свой context processor или template tag.

В render_to_response надо передовать RequestContext, но проще вместо render_to_response использовать функцию render, в нее нужно передавать request.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
dizballanze
@dizballanze
Software developer at Yandex
Вам нужно использовать request context processor
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы