Лично я большой поклонник декораторов, которые являются особенностью Python, которая не характерна для Django. Декораторы являются идеальным синтаксическим сахаром поверх функций более высокого порядка, и они особенно полезны для сокращения стандартного представления - вы можете быстро определить обобщенную функцию-обертку, в которую вы можете поместить повторяющийся код для легкого повторного использования и удобной. рефакторинг.
Вероятно, вам проще показать, чем объяснить, как они работают. Вот пример упрощенного просмотра:
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"),
}))
... но затем скажите, что вы хотите, чтобы эти страницы требовали от пользователя входа в систему. Вы можете добавить код входа в систему следующим образом:
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"),
}))
... который начинает заметно увеличиваться и повторяться даже для надуманного примера. Вы можете снова сделать свои функции тонкими с помощью декораторов, например:
из декоратора Импорт декоратора
@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):
(...)
Что происходит, если функция декоратора выполняется во время определения функции. 'F' в моем примере - это объект, представляющий функцию, к которой применяется декоратор, которой вы можете манипулировать бесконечным образом.
Для этого требуется библиотека декоратора , которая бесплатна для PyPI, как и многие хорошие кусочки Python, вы найдете.
Вам не нужна эта библиотека для написания функций декоратора, но это полезно, особенно в начале. Они могут сделать намного больше - любой вызывающий может быть декоратором; Вы можете украсить методы класса и перехватить переменную self
; декораторы могут быть прикованы, например, так:
@second
@first
def originalfunction(*args):
(...)
Я оставлю исследование того, что вы можете сделать с помощью такой простой функции высшего порядка для вас, если это понятие разожжет ваш аппетит. У меня есть еще много примеров для вас или любых других любопытных новых поклонников Python. Удачи.