Osobiście jestem wielkim fanem dekoratorów, które są funkcją Pythona, która nie jest specyficzna dla Django. Dekoratory są doskonałym cukrem syntaktycznym do funkcji wyższego rzędu i są szczególnie użyteczne w zmniejszaniu wymiaru znaków w widokach - możesz szybko zdefiniować uogólnioną funkcję owijania, w której możesz umieścić powtarzalny kod dla łatwego ponownego użycia i wygodnego -stop refaktoryzacji.
Najprawdopodobniej łatwiej jest Ci pokazać, niż wyjaśnić, jak działają. Oto uproszczony przykład widok:
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"),
}))
... ale potem powiedzieć, że chciał, aby te strony wymagać od użytkownika, aby zalogować się może dodać kod logowania tak:.
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"),
}))
.. ., który zaczyna być znacznie większy i powtarzalny, nawet dla wymyślonego przykładu. Można dokonać funkcje znowu szczupła z dekoratorów, tak:
od importu dekorator dekorator
@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):
(...)
Co się dzieje, jest funkcja dekorator jest wykonywany w momencie definicji funkcji. "F" w moim przykładzie to obiekt reprezentujący funkcję, do której stosuje się dekorator, który można manipulować na nieskończenie wiele sposobów.
Wymaga to decorator library, który jest darmowy dla PyPI, ponieważ znajdziesz wiele dobrych kądzików Pythona.
Nie potrzebujesz tej biblioteki do pisania funkcji dekoratora, ale jest to pomocne, szczególnie na początku. Mogą zrobić o wiele więcej - każda osoba wywołująca może być dekoratorem; możesz udekorować metody klasy i przechwycić zmienną self
; dekoratorzy mogą być na łańcuchu, tak jak poniżej:
@second
@first
def originalfunction(*args):
(...)
Zostawię poszukiwania tego, co można zrobić z takim łatwy wyższego rzędu funkcji manpipulation dla ciebie, powinno to pojęcie zaostrzy apetyt. Mam również wiele innych przykładów dla ciebie lub innych ciekawskich nowych miłośników Pythona. Powodzenia.
Nawiasem mówiąc, funkcja "otagowany()" w drugim fałszywym widoku nie jest literówką; to uproszczony interfejs napisałem do aplikacji do tagowania Django, również w nazwie skrótu bojowego, co ciekawscy znajdą tutaj: http://www.djangosnippets.org/snippets/1942/ – fish2000
Bardzo pomocni, dziękuję, dekoratorzy wydaje się mieć dla mnie wiele dodatkowych zastosowań. – neopickaze