Django - тег включения рендеринга из представления
поэтому мне было интересно, можно ли вернуть тег включения непосредственно из представления.
Страница - это обычная страница со списком элементов. Список элементов отображается с помощью тега включения. Если в представлении сделан запрос ajax, я хочу вернуть только то, что вернет тег включения, чтобы я мог добавить его на страницу через javascript. Что-то вроде этого возможно? Или я должен архивировать это лучше?
Ответы
Ответ 1
Это звучит как задание ярлыков render_to_string или render_to_response:
https://docs.djangoproject.com/en/dev/ref/templates/api/#the-render-to-string-shortcut
https://docs.djangoproject.com/en/dev/topics/http/shortcuts/#django.shortcuts.render_to_response
Мы все еще можем использовать тег включения для генерации контекста шаблона из наших аргументов (как это было отмечено в комментариях @BobStein-VisiBone)
from django.template.loader import render_to_string
from django.shortcuts import render_to_response
from .templatetags import my_inclusion_tag
rendered = render_to_string('my_include.html', my_inclusion_tag(foo='bar'))
#or
def my_view(request):
if request.is_ajax():
return render_to_response('my_include.html',
my_inclusion_tag(foo='bar'),
context_instance=RequestContext(request))
Ответ 2
Я пытался сделать то же самое сегодня и в итоге написал вспомогательную функцию для создания тегов шаблонов:
def render_templatetag(request, tag_string, tag_file, dictionary=None):
dictionary = dictionary or {}
context_instance = RequestContext(request)
context_instance.update(dictionary)
t = Template("{%% load %s %%}{%% %s %%}" % (tag_file, tag_string))
return t.render(context_instance)
tag_string - это вызов тега шаблона, который будет отображаться в обычном шаблоне, а tag_file - файл, который необходимо загрузить для тега шаблона.
Ответ 3
Это, безусловно, возможно. В представлении может отображаться любой шаблон, который может использовать тег включения. Преимущество этого подхода заключается в том, что вы можете использовать всю мощь шаблонов Django.
С другой стороны, ответы AJAX обычно не содержат HTML так же, как XML/JSON. Если вы используете функции шаблона Django, вам будет лучше с возвратом HTML. Если нет, то XML/JSON может иметь больше смысла. Только мои два цента.
Ответ 4
быстрый и грязный способ может состоять в том, чтобы иметь представление, которое отображает шаблон, который содержит только ваш templatetag.
Ответ 5
Используя тег включения с настраиваемым декоратором шаблонов, предоставленным Gonz, вместо стандартных тегов включения Django вы можете написать хелпер в своем представлении:
from django.template.loader import render_to_string
from home.templatetags.objectwidgets import object_widget
def _object_widget(request, obj):
template, context = object_widget(RequestContext(request), obj)
return render_to_string(template, context)
Он СУХОЙ и работает с Django 1.3 (я не тестировал его с Django 1.4).
Я использую эту технику, чтобы возвращать результаты поиска, отображаемые в HTML, через вызовы JSON/AJAX (ничего лучше, чем я придумал).
Ответ 6
Возможно, но, возможно, бит хаки, сложный или сложный.
Что бы я предложил, архитектор так, что у вас есть часть рендеринга в utils.py и используйте его в simple_tag вместо include_tag. Таким образом, вы можете легко использовать ту же функцию рендеринга utils в представлениях.
В моем (очень упрощенном) воображаемом примере у меня есть список пользователей и кнопка "Загрузить больше", которая возвращает больше пользователей.
счет /utils.py
from django.template.loader import render_to_string
def render_users(users):
return render_to_string("account/user_list_items.html", {"users": users})
счет /templatetags/account _tags.py
from django import template
from ..utils import render_users
register = template.Library()
@register.simple_tag
def list_users(users):
return render_users(users)
счет /views.py
from django.http import HttpResponse
from .models import User
from .utils import render_users
def load_more_users(request):
limit = request.GET["limit"]
offset = request.GET["offset"]
users = User.objects.all()[offset:offset + limit]
return HttpResponse(render_users(users))
Простой лучше, чем сложный.