Django.shortcuts.render: примеры (PYTHON)

Использование функции render для шаблонов в Django
Раздел: Веб-фреймворки, Шаблоны
django.shortcuts.render(request: django.http.HttpRequest, template_name: str, context: dict=None, content_type: str=None, status: int=None, using: str=None): django.http.HttpResponse

Функция django.shortcuts.render

Функция render() из модуля django.shortcuts представляет собой удобный инструмент для рендеринга HTML-шаблонов с заданным контекстом и возврата объекта HttpResponse. Использование функции типично для обработчиков представлений (views) в веб-приложениях на Django.

Функция выполняет комбинацию нескольких стандартных операций: загрузку шаблона, создание контекста, рендеринг шаблона и формирование HTTP-ответа. Такое объединение упрощает код представлений.

Аргументы функции:

  • request (обязательный): Объект HTTP-запроса, например, экземпляр HttpRequest. Он используется для извлечения информации, актуальной для рендеринга (например, текущий пользователь), и сохраняется в контексте шаблона, если не передано content_type.
  • template_name (обязательный): Строка или список/кортеж строк, определяющий имя или имена шаблонов для загрузки и рендеринга. Если передается последовательность, Django использует первый найденный шаблон.
  • context (необязательный): Словарь (или другой объект с интерфейсом отображения), содержащий данные для передачи в шаблон. По умолчанию используется пустой словарь.
  • content_type (необязательный): Значение MIME-типа для HTTP-заголовка Content-Type ответа. По умолчанию равно 'text/html'. Если этот аргумент указан, объект запроса не добавляется автоматически в контекст шаблона.
  • status (необязательный): Код состояния HTTP для ответа. По умолчанию равен 200.
  • using (необязательный): Имя механизма загрузки шаблонов, который следует использовать для рендеринга. Полезно при работе с несколькими настройками шаблонов.

Возвращаемое значение: Экземпляр HttpResponse, содержимое которого представляет результат рендеринга указанного шаблона с переданным контекстом.

Простое использование функции render

Базовый пример с обязательными аргументами.

from django.shortcuts import render

def simple_view(request):
    context = {'title': 'Главная страница', 'message': 'Добро пожаловать!'}
    return render(request, 'app/index.html', context)
# Результат: HttpResponse с отрендеренным HTML из шаблона 'app/index.html',
# куда переданы переменные title и message.

Использование списка имен шаблонов и нестандартного статуса.

def fallback_view(request):
    # Попытка загрузить 'app/custom.html', затем 'app/default.html'
    template_list = ['app/custom.html', 'app/default.html']
    return render(request, template_list, status=404)
# Если шаблон 'app/custom.html' не найден, будет использован 'app/default.html'.
# HTTP-ответ будет иметь статус 404.

Изменение типа контента ответа.

def xml_view(request):
    data = {'items': [1, 2, 3]}
    return render(request, 'data.xml', data, content_type='application/xml')
# Ответ будет содержать XML-данные с соответствующим заголовком Content-Type.
# Объект request не будет автоматически добавлен в контекст шаблона.

Альтернативные подходы и функции в Django

Непосредственная работа с классами Template и Context дает полный контроль, но требует больше кода.

from django.template import loader, RequestContext
from django.http import HttpResponse

def manual_render(request):
    template = loader.get_template('app/manual.html')
    context = {'data': 'Пример'}
    # RequestContext автоматически добавляет request и контекстные процессоры
    rendered_content = template.render(RequestContext(request, context))
    return HttpResponse(rendered_content)

Классовые представления (Class-Based Views) часто инкапсулируют логику рендеринга. Например, TemplateView.

from django.views.generic import TemplateView

class AboutView(TemplateView):
    template_name = 'app/about.html'

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['info'] = 'Дополнительные данные'
        return context

Функция render_to_response() исторически использовалась вместо render(), но не принимает объект запроса в качестве первого аргумента и не обрабатывает контекстные процессоры по умолчанию. В современных версиях Django ее применение ограничено.

Аналоги функции в других языках программирования

В PHP (фреймворк Laravel) метод view() хелпера или метод контроллера view() выполняют похожие задачи.

// Пример на PHP (Laravel)
public function show() {
    $data = ['title' => 'Home'];
    return view('greeting', $data); // Возвращает экземпляр Illuminate\View\View
}
// Шаблон 'greeting.blade.php' рендерится с переданными данными.

В JavaScript (фреймворк Express.js с шаблонизатором, например, Pug) используется метод res.render().

// Пример на JavaScript (Node.js, Express)
app.get('/', function(req, res) {
    res.render('index', { title: 'Express App', message: 'Hello' });
});
// Рендерится шаблон 'index.pug' и отправляется как HTML-ответ.

В Java (фреймворк Spring MVC) контроллеры часто возвращают имя представления, а модель заполняется атрибутами.

// Пример на Java (Spring)
@GetMapping("/")
public String home(Model model) {
    model.addAttribute("message", "Welcome");
    return "home"; // Имя Thymeleaf или JSP шаблона
}

В Golang с использованием html/template процесс требует явных шагов: парсинг шаблона и выполнение с данными.

// Пример на Golang
func handler(w http.ResponseWriter, r *http.Request) {
    tmpl := template.Must(template.ParseFiles("layout.html"))
    data := struct{ Title string }{Title: "Go Page"}
    tmpl.Execute(w, data) // Запись результата в ResponseWriter
}

Частые ошибки и проблемы

Передача контекста не в виде словаря приводит к ошибке TypeError.

# ОШИБКА
return render(request, 'template.html', 'just a string')
TypeError: context must be a dict rather than str.

Использование устаревшего параметра dictionary или context_instance в современных версиях Django.

# Устаревший код (Django < 1.8)
# return render(request, 'template.html', dictionary=...)
# return render_to_response('template.html', context_instance=RequestContext(request))
# В актуальных версиях эти параметры не поддерживаются.

Невнимательность к пространствам имен шаблонов или опечатки в именах файлов ведут к исключению TemplateDoesNotExist.

# Файл 'app/mytemplate.html' существует, но путь указан неверно.
return render(request, 'app/my_template.html', {})
django.template.exceptions.TemplateDoesNotExist: app/my_template.html

Попытка использовать переменные, не переданные в контексте, вызывает TemplateSyntaxError или отображает пустое значение в зависимости от шаблонизатора.

История изменений функции render

В Django 1.3 была представлена функция render() как удобная замена для распространенного паттерна render_to_response() с RequestContext.

Начиная с Django 1.8, аргумент context может быть любым объектом с интерфейсом отображения, а не только словарем. Это изменение связано с обновлением API шаблонов.

В Django 1.10 добавлена поддержка передачи request в контекст шаблона, только если не указан аргумент content_type. Ранее запрос всегда добавлялся.

Дальнейшие версии, включая Django 2.x, 3.x и 4.x, не вносили существенных изменений в сигнатуру или базовое поведение render(), поддерживая обратную совместимость. Акцент делается на стабильности этого ключевого компонента.

Расширенные и специальные примеры

Использование механизма using для рендеринга шаблона из альтернативной директории или движка.

Пример python
# В settings.py определены два бэкенда шаблонов: 'default' и 'admin'
def custom_engine_view(request):
    context = {'report': 'Данные'}
    return render(request, 'special/report.html', context, using='admin')

Комбинирование статического контекста из словаря и динамического из функции.

Пример python
def complex_view(request):
    base_context = {
        'site_name': 'Мой сайт',
        'year': 2023
    }
    dynamic_data = fetch_data_from_db() # Некая функция получения данных
    final_context = {**base_context, **dynamic_data}
    return render(request, 'app/complex.html', final_context)

Рендеринг шаблона без немедленного возврата HTTP-ответа, например, для формирования email или файла.

Пример python
from django.template import loader

def render_for_email(template_name, context_dict):
    # Используется loader для рендеринга без request
    template = loader.get_template(template_name)
    return template.render(context_dict)

html_body = render_for_email('email/welcome.html', {'user': user_obj})

Кастомизация ответа после рендеринга, например, добавление специальных заголовков.

Пример python
def view_with_headers(request):
    response = render(request, 'app/page.html', {'data': 'secret'})
    response['X-Custom-Header'] = 'MyValue'
    response['Cache-Control'] = 'no-cache'
    return response

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

Пример python
def namespace_view(request):
    # Будет искаться 'polls/detail.html' внутри установленного приложения 'polls'
    return render(request, 'polls:detail.html', {'question': question_obj})

питон django.shortcuts.render function comments

En
Django.shortcuts.render Render a template with context