Personalmente, soy un gran admirador de los decoradores, que son una característica de Python que no es específica de Django. Los decoradores son el azúcar sintáctico perfecto además de las funciones de orden superior, y son especialmente útiles para reducir las repeticiones en las vistas: puede definir rápidamente una función de envoltura generalizada, en la que puede poner el código repetitivo para facilitar su reutilización y conveniente. detener la refactorización.
Probablemente sea más fácil mostrarle que explicar cómo funcionan. He aquí un ejemplo de vista simplificada:
def listpage(request):
return HttpResponse(render_to_string("itemlist.html", {
"items": Item.objects.filter(visible=True).order_by("-modifydate")
}))
def itemlist_tags(request, tags):
return HttpResponse(render_to_string("itemlist.html", {
"items": Item.objects.tagged(name=tags).filter(visible=True).order_by("-modifydate"),
}))
... pero luego dijo que quería que estas páginas requieren que el usuario ingrese Es posible agregar el código de inicio de sesión de este modo:.
def listpage(request):
if not request.user.is_authenticated():
return f(request, *args, **kwargs)
else:
return HttpResponse(render_to_string("itemlist.html", {
"items": Item.objects.filter(visible=True).order_by("-modifydate")
}))
def itemlist_tags(request, tags):
if not request.user.is_authenticated():
return f(request, *args, **kwargs)
else:
return HttpResponse(render_to_string("itemlist.html", {
"items": Item.objects.tagged(name=tags).filter(visible=True).order_by("-modifydate"),
}))
.. .que está comenzando a ser notablemente más grande y repetitivo, incluso para un ejemplo artificial. Usted puede hacer sus funciones delgada de nuevo con decoradores, así:
del decorador decorador de importación
@decorator
def loginrequired(f, request, *args, **kwargs):
if request.user.is_authenticated():
return f(request, *args, **kwargs)
else:
return HttpResponseRedirect("/")
@loginrequired
def listpage(request):
return HttpResponse(render_to_string("itemlist.html", {
"items": Item.objects.filter(visible=True).order_by("-modifydate")
}))
@loginrequired
def itemlist_tags(request, tags):
return HttpResponse(render_to_string("itemlist.html", {
"items": Item.objects.tagged(name=tags).filter(visible=True).order_by("-modifydate"),
}))
@loginrequired
def another_such_function(request):
(...)
@loginrequired
def and_again(request):
(...)
lo que sucede es la función decoradora se ejecuta en el momento de la definición de la función. La 'f' en mi ejemplo es un objeto que representa la función a la que se aplica el decorador, que puede manipular de manera interminable.
Esto requiere el decorator library, que es gratis en PyPI, como lo son muchos buenos bocados de pitón, usted encontrará.
No necesita esta biblioteca para escribir funciones de decorador, pero es útil, especialmente al principio. Pueden hacer mucho más: cualquier llamante puede ser un decorador; puede decorar métodos de clase e interceptar la variable self
; decoradores pueden ser encadenados, así:
@second
@first
def originalfunction(*args):
(...)
Voy a dejar la exploración de lo que puede hacer con tales manpipulation sencilla función de orden superior para usted, esta noción debe abrir el apetito. También tengo muchos más ejemplos, para ti o cualquier otro curioso nuevo aficionado de Python. Buena suerte.
Por cierto, la función 'etiquetada()' en la segunda vista falsa no es un error tipográfico; es una interfaz simplificada que escribí en la aplicación django-tagging, también en el nombre de la reducción de etiquetas, que los curiosos encontrarán aquí: http://www.djangosnippets.org/snippets/1942/ – fish2000
Muy útil, gracias, decoradores parece tener muchos usos adicionales para mí. – neopickaze