Personalmente sono un grande fan dei decoratori, che sono una funzione python non specifica di Django. I decoratori sono lo zucchero sintattico perfetto in aggiunta alle funzioni di ordine superiore e sono particolarmente utili per ridurre lo schema di stampa nelle viste: è possibile definire rapidamente una funzione di wrapper generalizzata, in cui è possibile inserire il codice ripetitivo per un facile riutilizzo e uno conveniente fermare il refactoring
Probabilmente è più facile mostrarti che spiegare come funzionano. Ecco un esempio di visualizzazione semplificata:
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"),
}))
... ma poi detto che volevi fare queste pagine richiedono all'utente di accedere Si potrebbe aggiungere il codice di accesso in questo 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"),
}))
.. che sta iniziando a diventare notevolmente più grande e ripetitivo, anche per un esempio forzato. È possibile effettuare le funzioni sottile di nuovo con decoratori, in questo modo:
da decoratore importazione decoratore
@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):
(...)
ciò che accade è la funzione decoratore viene eseguita al momento della definizione della funzione. La 'f' nel mio esempio è un oggetto che rappresenta la funzione a cui è applicato il decoratore, che puoi manipolare in modi infiniti.
Ciò richiede il decorator library, che è gratuito su PyPI come lo sono molti buoni bocconcini di pitone, lo troverete.
Non hai bisogno di questa libreria per scrivere le funzioni di decoratore, ma è utile, specialmente all'inizio. Possono fare molto di più - qualsiasi chiamabile può essere un decoratore; puoi decorare i metodi di classe e intercettare la variabile self
; decoratori possono essere concatenati up, in questo modo:
@second
@first
def originalfunction(*args):
(...)
Lascio l'esplorazione di ciò che si può fare con tale funzione semplice di ordine superiore manpipulation per te, dovrebbe questa nozione stuzzicare l'appetito. Ho anche molti altri esempi, per te o per qualsiasi altro curioso nuovo appassionato di pitone. In bocca al lupo.
A proposito, la funzione 'tagged()' nella seconda vista falsa non è un refuso; è un'interfaccia semplificata che ho scritto sull'app django-tagging, anche nel nome della riduzione del boilerplate, che i curiosi troveranno qui: http://www.djangosnippets.org/snippets/1942/ – fish2000
Molto utile, grazie, decoratori sembrano avere molti usi extra per me. – neopickaze