2010-08-18 10 views
14

, por lo que me preguntaba si podría devolver una etiqueta de inclusión directamente desde una vista.Django: etiqueta de inclusión de representación desde una vista

La página es una página normal con una lista de elementos. La lista de elementos se representa con una etiqueta de inclusión. Si se realiza una solicitud de AJAX a la vista, quiero devolver solo lo que devolvería la etiqueta de inclusión para poder agregarla a la página a través de JavaScript. Es algo como esto posible? ¿O debería diseñar esto mejor?

Respuesta

0

Esto es ciertamente posible. Una vista puede representar cualquier plantilla que pueda contener una etiqueta de inclusión. La ventaja de este enfoque es que puede aprovechar toda la fortaleza de las plantillas de Django.

Por otro lado, las respuestas AJAX normalmente no contienen HTML tanto como XML/JSON. Si está utilizando las características de la plantilla de Django, es mejor devolver el HTML. De lo contrario, XML/JSON podría tener más sentido. Solo mis dos centavos.

+0

Siempre he tenido un problema al devolver xml/json y luego tener javascript renderizar los datos en html. No está violando los principios DRY porque ahora tenemos el código duplicado en la plantilla de django y en el javascript. – killerbarney

+0

Menciona que se puede hacer, pero no incluye un ejemplo. ¿Puede mostrarme cómo hacerlo o una página que lo tiene? – killerbarney

0

manera rápida y sucia podría ser para tener una vista, que rinde una plantilla, que solo contiene su templatetag.

+0

ya, de esta manera parecía ser redundante en el código, esperaba algo que no implicara ese paso adicional. – killerbarney

+0

luego exponga los modelos serializados como json, consulte http://code.google.com/p/django-rest-interface/ para empezar, o despliegue su propia aplicación, use un espacio de nombres de URL diferente en lugar de ramificar en su existente ¡vistas! – sjh

1

yo estaba tratando de hacer exactamente lo mismo hoy, y terminé escribiendo una función de ayuda para hacer etiquetas de plantilla:

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 es la llamada a la etiqueta de plantilla, ya que aparecerían en una normalidad plantilla, y tag_file es el archivo que necesita cargar para la etiqueta de la plantilla.

+0

esto es bastante inútil, la representación de la etiqueta debe hacerse en una plantilla en lugar de en el código de vista. puede usar la etiqueta de inclusión para evitar la duplicación del código de la plantilla. – Anentropic

+0

Haciéndolo de esta manera meands que no tiene que repetir el nombre de la plantilla para representar en su vista –

+0

@Craig sí, pero tiene que repetir la cadena de etiquetas utilizada en la plantilla en su vista, ya no es SECO – Anentropic

2

Esto suena como un trabajo para los render_to_string o render_to_response atajos:
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

todavía podemos utilizar la etiqueta de inclusión para generar un diccionario contexto de la plantilla de nuestros argumentos (como amablemente señalado por @BobStein -VisiBone en los comentarios)

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)) 
+0

Haciéndolo de esta manera meands que tiene que repetir el nombre de la plantilla para representar en su vista, lo que rompe el principio DRY –

+0

@Craig recuperar el DRY es trivial, simplemente almacene el nombre de la plantilla en una variable y use la var en su vista y donde se define la etiqueta de inclusión – Anentropic

+1

No es que el OP haya dado ningún ejemplo para empezar, pero lo que le falta a usted es cualquier mención a la función de etiqueta de inclusión. Resulta que, aunque está decorado, todavía se puede llamar directamente para generar un diccionario listo para render_to_string(). Sugiero reemplazar ambos diccionarios en su código con: 'my_inclusion_tag_function (arguments)' y agregar en la parte superior 'from templatetags.my_file include my_inclusion_tag_function' o algo así. –

0

Usando inclusion tag with configurable template decorator provided by Gonz en lugar de etiquetas de inclusión por defecto de Django puede escribir un ayudante en su opinión:

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) 

Es SECO y trabaja con Django 1.3 (no he probado con Django 1.4).

Utilizo esta técnica para devolver los resultados de búsqueda representados en HTML a través de llamadas JSON/AJAX (nada mejor que se me ocurrió).

0

Es posible, pero probablemente poco hacky, complejo o complicado.

Lo que yo sugeriría es que sea un arquitecto para que tenga la parte de representación en la función utils.py y la use en una etiqueta simple en lugar de una etiqueta_in inclusión. De esta forma, puede usar la misma función de representación de utilidades fácilmente en las vistas.

En mi ejemplo imaginario (muy simplificado) tengo una lista de usuarios y un botón "Cargar más" que devuelve más usuarios.

cuenta/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}) 

cuenta/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) 

cuenta/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)) 

simple es mejor que complejo.

Cuestiones relacionadas