python - examples - django template variable
¿Django favorito consejos y características? (30)
Inspirado por la serie de preguntas ''Características ocultas de ...'', tengo curiosidad por conocer sus consejos favoritos de Django o características menos conocidas pero útiles que conozca.
- Por favor, incluya solo un consejo por respuesta.
- Agregue los requisitos de versión de Django si hay alguno.
Los procesadores de contexto son impresionantes.
Digamos que tienes un modelo de usuario diferente y quieres incluirlo en cada respuesta. En lugar de hacer esto:
def myview(request, arg, arg2=None, template=''my/template.html''):
'''''' My view... ''''''
response = dict()
myuser = MyUser.objects.get(user=request.user)
response[''my_user''] = myuser
...
return render_to_response(template,
response,
context_instance=RequestContext(request))
Los procesos de contexto le permiten pasar cualquier variable a sus plantillas. Normalmente pongo el mío en ''my_project/apps/core/context.py
:
def my_context(request):
try:
return dict(my_user=MyUser.objects.get(user=request.user))
except ObjectNotFound:
return dict(my_user='''')
En su settings.py
agregue la siguiente línea a su TEMPLATE_CONTEXT_PROCESSORS
TEMPLATE_CONTEXT_PROCESSORS = (
''my_project.apps.core.context.my_context'',
...
)
Ahora, cada vez que se realiza una solicitud, incluye la clave my_user
automáticamente.
También las signals ganar.
Escribí una publicación de blog sobre esto hace unos meses, así que simplemente voy a cortar y pegar:
Fuera de la caja Django te da varias señales que son increíblemente útiles. Tiene la capacidad de hacer cosas antes y después de guardar, iniciar, eliminar o incluso cuando se está procesando una solicitud. Así que vamos a alejarnos de los conceptos y demostrar cómo se utilizan. Digamos que tenemos un blog
from django.utils.translation import ugettext_lazy as _
class Post(models.Model):
title = models.CharField(_(''title''), max_length=255)
body = models.TextField(_(''body''))
created = models.DateTimeField(auto_now_add=True)
Así que de alguna manera quieres notificar a uno de los muchos servicios de blogging que hemos realizado una nueva publicación, reconstruir el caché de publicaciones más reciente y tuitearlo. Bien, con las señales, tiene la capacidad de hacer todo esto sin tener que agregar ningún método a la clase Post.
import twitter
from django.core.cache import cache
from django.db.models.signals import post_save
from django.conf import settings
def posted_blog(sender, created=None, instance=None, **kwargs):
'''''' Listens for a blog post to save and alerts some services. ''''''
if (created and instance is not None):
tweet = ''New blog post! %s'' instance.title
t = twitter.PostUpdate(settings.TWITTER_USER,
settings.TWITTER_PASSWD,
tweet)
cache.set(instance.cache_key, instance, 60*5)
# send pingbacks
# ...
# whatever else
else:
cache.delete(instance.cache_key)
post_save.connect(posted_blog, sender=Post)
Ahí vamos, definiendo esa función y utilizando la señal post_init para conectar la función al modelo Post y ejecutarla después de que se haya guardado.
¡No codifiques tus URLs!
Utilice nombres de URL en su lugar, y la función reverse
para obtener la propia URL.
Cuando defina sus asignaciones de URL, asigne nombres a sus URL.
urlpatterns += (''project.application.views''
url( r''^something/$'', ''view_function'', name="url-name" ),
....
)
Asegúrese de que el nombre sea único por URL.
Por lo general, tengo un formato consistente "proyecto-aplicación-vista", por ejemplo, "cbx-forum-thread" para una vista de hilo.
ACTUALIZACIÓN (robando descaradamente la adición de ayaz ):
Este nombre se puede utilizar en plantillas con la etiqueta url
.
Agregue assert False
en su código de vista para volcar la información de depuración.
Al intentar intercambiar datos entre Django y otra aplicación, request.raw_post_data
es un buen amigo. Úselo para recibir y procesar de forma personalizada, por ejemplo, datos XML.
Documentación: http://docs.djangoproject.com/en/dev/ref/request-response/
Aprendí esto de la documentación de la aplicación sorl-thumbnails . Puede usar la palabra clave "como" en las etiquetas de plantilla para usar los resultados de la llamada en otra parte de su plantilla.
Por ejemplo:
{% url image-processor uid as img_src %}
<img src="{% thumbnail img_src 100x100 %}"/>
Esto se menciona de pasada en la documentación de Django templatetag, pero solo en referencia a los bucles. No dicen que puedes usar esto en otro lugar (¿en cualquier lugar?) También.
Cuando estaba empezando, no sabía que había un Paginator , ¡¡asegúrate de que sepas de su existencia !!
Dado que las "vistas" de Django solo tienen que ser llamadas que devuelvan un HttpResponse, puede crear fácilmente vistas basadas en clases como las de Ruby on Rails y otros marcos.
Hay varias formas de crear vistas basadas en clases, aquí está mi favorito:
from django import http
class RestView(object):
methods = (''GET'', ''HEAD'')
@classmethod
def dispatch(cls, request, *args, **kwargs):
resource = cls()
if request.method.lower() not in (method.lower() for method in resource.methods):
return http.HttpResponseNotAllowed(resource.methods)
try:
method = getattr(resource, request.method.lower())
except AttributeError:
raise Exception("View method `%s` does not exist." % request.method.lower())
if not callable(method):
raise Exception("View method `%s` is not callable." % request.method.lower())
return method(request, *args, **kwargs)
def get(self, request, *args, **kwargs):
return http.HttpResponse()
def head(self, request, *args, **kwargs):
response = self.get(request, *args, **kwargs)
response.content = ''''
return response
Puede agregar todo tipo de otras cosas, como el manejo y autorización de solicitudes condicionales en su vista base.
Una vez que haya configurado sus vistas, urls.py se verá así:
from django.conf.urls.defaults import *
from views import MyRestView
urlpatterns = patterns('''',
(r''^restview/'', MyRestView.dispatch),
)
De la documentación de django-admin :
Si usa el shell Bash, considere instalar el script de finalización de bash de Django, que se encuentra en extras/django_bash_completion
en la distribución de Django. Permite la tabulación de los comandos django-admin.py
y manage.py
, por lo que puede, por ejemplo ...
- Escribe
django-admin.py
. - Presione [TAB] para ver todas las opciones disponibles.
- Escriba
sql
, luego [TAB], para ver todas las opciones disponibles cuyos nombres comienzan consql
.
Ejecute un servidor SMTP de desarrollo que solo generará lo que se le envíe (si no desea instalar SMTP en su servidor de desarrollo).
línea de comando:
python -m smtpd -n -c DebuggingServer localhost:1025
El ./manage.py runserver_plus
facilty que viene con django_extensions es realmente impresionante.
Crea una página de depuración mejorada que, entre otras cosas, utiliza el depurador Werkzeug para crear consolas de depuración interactivas para cada punto de la pila (ver captura de pantalla). También proporciona un método de depuración muy útil y útil dump()
para mostrar información sobre un objeto / marco.
Para instalar, puedes usar pip:
pip install django_extensions
pip install Werkzeug
Luego agregue ''django_extensions''
a su tupla INSTALLED_APPS
en settings.py
e inicie el servidor de desarrollo con la nueva extensión:
./manage.py runserver_plus
Esto cambiará la forma en que se depura.
En lugar de usar render_to_response
para vincular su contexto a una plantilla y representarlo (que es lo que suelen mostrar los documentos de Django) use la vista genérica direct_to_template
. Hace lo mismo que render_to_response
, pero también agrega automáticamente RequestContext al contexto de la plantilla, permitiendo implícitamente que se utilicen los procesadores de contexto. Puedes hacer esto manualmente usando render_to_response
, pero ¿para qué molestarse? Es solo otro paso para recordar y otro LOC. Además de utilizar procesadores de contexto, tener RequestContext en su plantilla le permite hacer cosas como:
<a href="{{MEDIA_URL}}images/frog.jpg">A frog</a>
lo cual es muy útil. De hecho, +1 en vistas genéricas en general. La mayoría de los documentos de Django los muestran como accesos directos para ni siquiera tener un archivo views.py para aplicaciones simples, pero también puede usarlos dentro de sus propias funciones de visualización:
from django.views.generic import simple
def article_detail(request, slug=None):
article = get_object_or_404(Article, slug=slug)
return simple.direct_to_template(request,
template="articles/article_detail.html",
extra_context={''article'': article}
)
Esto se agrega a la respuesta anterior sobre los nombres de URL de Django y el envío de URL inversa .
Los nombres de URL también pueden ser utilizados efectivamente dentro de las plantillas. Por ejemplo, para un patrón de URL dado:
url(r''(?P<project_id>/d+)/team/$'', ''project_team'', name=''project_team'')
Puedes tener lo siguiente en plantillas:
<a href="{% url project_team project.id %}">Team</a>
Hay un conjunto de etiquetas personalizadas que uso en todas las plantillas de mi sitio. Buscando una forma de cargarlo automáticamente (DRY, ¿recuerdas?), Encontré lo siguiente:
from django import template
template.add_to_builtins(''project.app.templatetags.custom_tag_module'')
Si coloca esto en un módulo que está cargado de forma predeterminada (su urlconf principal, por ejemplo), tendrá las etiquetas y los filtros de su módulo de etiquetas personalizadas disponibles en cualquier plantilla, sin usar {% load custom_tag_module %}
.
El argumento pasado a template.add_to_builtins()
puede ser cualquier ruta de módulo; Su módulo de etiqueta personalizado no tiene que vivir en una aplicación específica. Por ejemplo, también puede ser un módulo en el directorio raíz de su proyecto (por ejemplo, ''project.custom_tag_module''
).
Instale Django Command Extensions y pygraphviz y luego pygraphviz el siguiente comando para obtener una visualización del modelo Django realmente agradable:
./manage.py graph_models -a -g -o my_project.png
La aplicación de diseño web es muy útil cuando comienza a diseñar su sitio web. Una vez importado, puede agregar esto para generar texto de ejemplo:
{% load webdesign %}
{% lorem 5 p %}
Me gusta usar el depurador Python pdb para depurar proyectos Django.
Este es un enlace útil para aprender a usarlo: http://www.ferg.org/papers/debugging_in_python.html
No escriba sus propias páginas de inicio de sesión. Si estás utilizando django.contrib.auth.
El secreto real y sucio es que si también está utilizando django.contrib.admin, y django.template.loaders.app_directories.load_template_source está en sus cargadores de plantillas, ¡ también puede obtener sus plantillas gratis!
# somewhere in urls.py
urlpatterns += patterns(''django.contrib.auth'',
(r''^accounts/login/$'',''views.login'', {''template_name'': ''admin/login.html''}),
(r''^accounts/logout/$'',''views.logout''),
)
No tengo la reputación suficiente para responder al comentario en cuestión, pero es importante tener en cuenta que si va a utilizar Jinja , NO es compatible con el carácter ''-'' en los nombres de bloque de la plantilla, mientras que Django sí. Esto me causó muchos problemas y desperdició tiempo intentando rastrear el mensaje de error muy oscuro que generó.
Todo el mundo sabe que hay un servidor de desarrollo que puede ejecutar con "manage.py runserver", pero ¿sabía que existe una vista de desarrollo para servir archivos estáticos (CSS / JS / IMG) también?
Los recién llegados siempre están desconcertados porque Django no viene con ninguna forma de servir archivos estáticos. Esto se debe a que el equipo de desarrolladores cree que es el trabajo para un servidor web de la vida real.
Pero al desarrollar, es posible que no desee configurar Apache + mod_wisgi, es pesado. Luego puedes agregar lo siguiente a urls.py:
(r''^site_media/(?P<path>.*)$'', ''django.views.static.serve'',
{''document_root'': ''/path/to/media''}),
Su CSS / JS / IMG estará disponible en www.yoursite.com/site_media/.
Por supuesto, no lo use en un entorno de producción.
Usa IPython para saltar a tu código en cualquier nivel y depura usando el poder de IPython. Una vez que haya instalado IPython, simplemente coloque este código en el lugar donde desee depurar:
from IPython.Shell import IPShellEmbed; IPShellEmbed()()
Luego, actualice la página, vaya a la ventana del servidor de ejecución y estará en una ventana interactiva de IPython.
Tengo un fragmento de código configurado en TextMate, así que simplemente escribo ipshell y presiono la pestaña. No podría vivir sin eso.
Usa Jinja2 junto a Django.
Si encuentra que el lenguaje de la plantilla de Django es extremadamente restringido (¡como yo!), Entonces no tiene por qué estar atascado con él. Django es flexible, y el idioma de la plantilla está acoplado al resto del sistema, por lo que simplemente conecte otro idioma de la plantilla y utilícelo para representar sus respuestas http.
Yo uso Jinja2 , es casi como una versión de encendido del lenguaje de plantillas de django, usa la misma sintaxis y te permite usar expresiones en sentencias if. ¡Ya no hay que crear etiquetas personalizadas como if_item_in_list
! simplemente puede decir %{ if item in list %}
, o {% if object.field < 10 %}
.
Pero eso no es todo; Tiene muchas más funciones para facilitar la creación de plantillas, que no puedo ver todas aquí.
Use django-annoying''s decorador render_to
django-annoying''s lugar de render_to_response
.
@render_to(''template.html'')
def foo(request):
bars = Bar.objects.all()
if request.user.is_authenticated():
return HttpResponseRedirect("/some/url/")
else:
return {''bars'': bars}
# equals to
def foo(request):
bars = Bar.objects.all()
if request.user.is_authenticated():
return HttpResponseRedirect("/some/url/")
else:
return render_to_response(''template.html'',
{''bars'': bars},
context_instance=RequestContext(request))
Editado para señalar que devolver una HttpResponse (como una redirección) cortocircuitará al decorador y funcionará como usted espera.
Use xml_models para crear modelos de Django que usen un backend API REST XML (en lugar de uno de SQL). Esto es muy útil, especialmente cuando modelas API de terceros: obtienes la misma sintaxis QuerySet a la que estás acostumbrado. Puedes instalarlo desde PyPI.
XML desde una API:
<profile id=4>
<email>[email protected]</email>
<first_name>Joe</first_name>
<last_name>Example</last_name>
<date_of_birth>1975-05-15</date_of_birth>
</profile>
Y ahora en python:
class Profile(xml_models.Model):
user_id = xml_models.IntField(xpath=''/profile/@id'')
email = xml_models.CharField(xpath=''/profile/email'')
first = xml_models.CharField(xpath=''/profile/first_name'')
last = xml_models.CharField(xpath=''/profile/last_name'')
birthday = xml_models.DateField(xpath=''/profile/date_of_birth'')
finders = {
(user_id,): settings.API_URL +''/api/v1/profile/userid/%s'',
(email,): settings.API_URL +''/api/v1/profile/email/%s'',
}
profile = Profile.objects.get(user_id=4)
print profile.email
# would print ''[email protected]''
También puede manejar relaciones y colecciones. Lo usamos todos los días en el código de producción muy utilizado, por lo que, aunque es beta, es muy útil. También tiene un buen conjunto de talones que puede usar en sus pruebas.
(Descargo de responsabilidad: si bien no soy el autor de esta biblioteca, ahora soy un comentarista, después de haber realizado algunos compromisos menores)
Utilice la barra de herramientas de depuración de Django . Por ejemplo, permite ver todas las consultas SQL realizadas mientras se renderiza la vista y también puede ver el seguimiento de pila para cualquiera de ellas.
Utilizar migraciones de base de datos. Usa el sur .
Voy a empezar con un consejo de mi parte :)
Use os.path.dirname () en settings.py para evitar nombres de archivos codificados.
No cree una ruta de código en su configuración.py si desea ejecutar su proyecto en diferentes ubicaciones. Use el siguiente código en settings.py si sus plantillas y archivos estáticos se encuentran dentro del directorio del proyecto Django:
# settings.py
import os
PROJECT_DIR = os.path.dirname(__file__)
...
STATIC_DOC_ROOT = os.path.join(PROJECT_DIR, "static")
...
TEMPLATE_DIRS = (
os.path.join(PROJECT_DIR, "templates"),
)
Créditos: obtuve esta sugerencia del screencast '' Django From the Ground Up ''.
django.views.generic.list_detail.object_list - Proporciona todas las variables lógicas y de plantilla para la paginación (una de esas docenas que he escrito-que-mil-veces-ahora). Envolviéndolo permite cualquier lógica que necesites. Esta gema me ha ahorrado muchas horas de depuración de errores off-by-one en mis páginas de "Resultados de búsqueda" y hace que el código de visualización sea más limpio en el proceso.
Virtualenv + Python = salvavidas si está trabajando en varios proyectos de Django y existe la posibilidad de que no dependan de la misma versión de Django / una aplicación.
PyCharm IDE es un entorno agradable para codificar y especialmente para depurar, con soporte incorporado para Django.
django.db.models.get_model
le permite recuperar un modelo sin importarlo.
James muestra lo útil que puede ser: "Sugerencias de Django: Escribir mejores etiquetas de plantilla - Iteración 4" .