Существуют стандартные встроенные декораторы для запроса определенного метода HTTP или списка разрешенных методов.
См. Код: http://code.djangoproject.com/browser/ django / trunk / django / views / decorators / http.py .
Обновленный ответ в 2016 году: Современный Django имеет все необходимое, встроенное и доступное через представления на основе классов . В наиболее простой форме канонический подход состоит в разделении на подклассы django.views.generic.View
и реализации методов класса, названных в честь HTTP-глаголов:
class MyView(View):
def get(self, request, *args, **kwargs):
# ...
def post(self, request, *args, **kwargs):
# ...
Внутренне это работает очень похоже на мой древний код ниже (который был написан до того, как в Django появились представления на основе классов). Существует метод View.dispatch
, который в основном ищет, что вызывать, или возвращает 405, если ничего не может найти: getattr (self, request.method.lower (), self.http_method_not_allowed )
.
Конечно, если вы занимаетесь обработкой форм, рендерингом шаблонов или обычными CRUD-материалами, обязательно ознакомьтесь с доступными подклассами View
.
Устаревший ответ от 2009 года ниже. Код все еще работает в 2016 году, но не является СУХИМ решением, поэтому не используйте его. В 2011 году Django получил представления на основе классов, и в настоящее время они представляют собой стандартный способ работы. Я сохраняю это здесь исключительно в исторических целях. Старый текст ответа:
В одном конкретном представлении, где мне нужно иметь отдельный код для разных HTTP-методов (это моя крошечная реализация WebDAV), я делаю что-то вроде этого:
class SomeView(object):
def method_get(self, request, ...):
...
def __call__(self, request, *args, **kwargs):
m = getattr(self, 'method_%s' % request.method.lower(), None)
if m is not None:
return m(request, user, *args, **kwargs)
return HttpResponseNotAllowed("405 Method Not Allowed")
# Then url(r'...', SomeView()),
Добавлено / отредактировано: Ну, я немного подумал и реализовал подход декоратора. Это не так плохо, как я первоначально думал.
def method_not_allowed_view(request, *args, **kwargs):
return HttpResponseNotAllowed("405 Method Not Allowed")
def http_method(*methods):
methods = map(lambda m: m.lower(), methods)
def __method_wrapper(f):
this_module = __import__(__name__)
chain = getattr(this_module, f.__name__, method_not_allowed_view)
base_view_func = lambda request, *args, **kwargs: \
f(request, *args, **kwargs) if request.method.lower() in methods \
else chain(request, *args, **kwargs)
setattr(this_module, f.__name__, base_view_func)
return base_view_func
return __method_wrapper
@http_method('get')
def my_view(request):
return HttpResponse("Thank you for GETting.")
@http_method('post', 'put')
def my_view(request):
return HttpResponse("Thank you for POSTing or PUTting.")
# url(r'...', 'app.my_view'),
В любом случае этот пост является вики-страницей сообщества, так что не стесняйтесь улучшать, если вам нравится идея! И история изменений также содержит несколько других подходов, которые я пробовал перед написанием этой статьи ...
Код по-прежнему работает в 2016 году, но не является СУХИМ решением, поэтому не используйте его. В 2011 году Django получил представления на основе классов, и в настоящее время они представляют собой стандартный способ работы. Я сохраняю это здесь исключительно в исторических целях. Старый текст ответа:В одном конкретном представлении, где мне нужно иметь отдельный код для разных HTTP-методов (это моя крошечная реализация WebDAV), я делаю что-то вроде этого:
class SomeView(object):
def method_get(self, request, ...):
...
def __call__(self, request, *args, **kwargs):
m = getattr(self, 'method_%s' % request.method.lower(), None)
if m is not None:
return m(request, user, *args, **kwargs)
return HttpResponseNotAllowed("405 Method Not Allowed")
# Then url(r'...', SomeView()),
Добавлено / отредактировано: Ну, я немного подумал и реализовал подход декоратора. Это не так плохо, как я первоначально думал.
def method_not_allowed_view(request, *args, **kwargs):
return HttpResponseNotAllowed("405 Method Not Allowed")
def http_method(*methods):
methods = map(lambda m: m.lower(), methods)
def __method_wrapper(f):
this_module = __import__(__name__)
chain = getattr(this_module, f.__name__, method_not_allowed_view)
base_view_func = lambda request, *args, **kwargs: \
f(request, *args, **kwargs) if request.method.lower() in methods \
else chain(request, *args, **kwargs)
setattr(this_module, f.__name__, base_view_func)
return base_view_func
return __method_wrapper
@http_method('get')
def my_view(request):
return HttpResponse("Thank you for GETting.")
@http_method('post', 'put')
def my_view(request):
return HttpResponse("Thank you for POSTing or PUTting.")
# url(r'...', 'app.my_view'),
В любом случае этот пост является вики-страницей сообщества, так что не стесняйтесь улучшать, если вам нравится идея! И история изменений также содержит несколько других подходов, которые я пробовал перед написанием этой статьи ...
Код по-прежнему работает в 2016 году, но не является СУХИМ решением, поэтому не используйте его. В 2011 году Django получил представления на основе классов, и в настоящее время они представляют собой стандартный способ работы. Я сохраняю это здесь исключительно в исторических целях. Старый текст ответа:В одном конкретном представлении, где мне нужно иметь отдельный код для разных HTTP-методов (это моя крошечная реализация WebDAV), я делаю что-то вроде этого:
class SomeView(object):
def method_get(self, request, ...):
...
def __call__(self, request, *args, **kwargs):
m = getattr(self, 'method_%s' % request.method.lower(), None)
if m is not None:
return m(request, user, *args, **kwargs)
return HttpResponseNotAllowed("405 Method Not Allowed")
# Then url(r'...', SomeView()),
Добавлено / отредактировано: Ну, я немного подумал и реализовал подход декоратора. Это не так плохо, как я первоначально думал.
def method_not_allowed_view(request, *args, **kwargs):
return HttpResponseNotAllowed("405 Method Not Allowed")
def http_method(*methods):
methods = map(lambda m: m.lower(), methods)
def __method_wrapper(f):
this_module = __import__(__name__)
chain = getattr(this_module, f.__name__, method_not_allowed_view)
base_view_func = lambda request, *args, **kwargs: \
f(request, *args, **kwargs) if request.method.lower() in methods \
else chain(request, *args, **kwargs)
setattr(this_module, f.__name__, base_view_func)
return base_view_func
return __method_wrapper
@http_method('get')
def my_view(request):
return HttpResponse("Thank you for GETting.")
@http_method('post', 'put')
def my_view(request):
return HttpResponse("Thank you for POSTing or PUTting.")
# url(r'...', 'app.my_view'),
В любом случае этот пост является вики-страницей сообщества, так что не стесняйтесь улучшать, если вам нравится идея! И история изменений также содержит несколько других подходов, которые я пробовал перед написанием этой статьи ...
так что не используйте это. В 2011 году Django получил представления на основе классов, и в настоящее время они представляют собой стандартный способ работы. Я сохраняю это здесь исключительно в исторических целях. Старый текст ответа:В одном конкретном представлении, где мне нужно иметь отдельный код для разных HTTP-методов (это моя крошечная реализация WebDAV), я делаю что-то вроде этого:
class SomeView(object):
def method_get(self, request, ...):
...
def __call__(self, request, *args, **kwargs):
m = getattr(self, 'method_%s' % request.method.lower(), None)
if m is not None:
return m(request, user, *args, **kwargs)
return HttpResponseNotAllowed("405 Method Not Allowed")
# Then url(r'...', SomeView()),
Добавлено / отредактировано: Ну, я немного подумал и реализовал подход декоратора. Это не так плохо, как я первоначально думал.
def method_not_allowed_view(request, *args, **kwargs):
return HttpResponseNotAllowed("405 Method Not Allowed")
def http_method(*methods):
methods = map(lambda m: m.lower(), methods)
def __method_wrapper(f):
this_module = __import__(__name__)
chain = getattr(this_module, f.__name__, method_not_allowed_view)
base_view_func = lambda request, *args, **kwargs: \
f(request, *args, **kwargs) if request.method.lower() in methods \
else chain(request, *args, **kwargs)
setattr(this_module, f.__name__, base_view_func)
return base_view_func
return __method_wrapper
@http_method('get')
def my_view(request):
return HttpResponse("Thank you for GETting.")
@http_method('post', 'put')
def my_view(request):
return HttpResponse("Thank you for POSTing or PUTting.")
# url(r'...', 'app.my_view'),
В любом случае этот пост является вики-страницей сообщества, так что не стесняйтесь улучшать, если вам нравится идея! И история изменений также содержит несколько других подходов, которые я пробовал перед написанием этой статьи ...
так что не используйте это. В 2011 году Django получил представления на основе классов, и в настоящее время они представляют собой стандартный способ работы. Я сохраняю это здесь исключительно в исторических целях. Старый текст ответа:В одном конкретном представлении, где мне нужно иметь отдельный код для разных HTTP-методов (это моя крошечная реализация WebDAV), я делаю что-то вроде этого:
class SomeView(object):
def method_get(self, request, ...):
...
def __call__(self, request, *args, **kwargs):
m = getattr(self, 'method_%s' % request.method.lower(), None)
if m is not None:
return m(request, user, *args, **kwargs)
return HttpResponseNotAllowed("405 Method Not Allowed")
# Then url(r'...', SomeView()),
Добавлено / отредактировано: Ну, я немного подумал и реализовал подход декоратора. Это не так плохо, как я первоначально думал.
def method_not_allowed_view(request, *args, **kwargs):
return HttpResponseNotAllowed("405 Method Not Allowed")
def http_method(*methods):
methods = map(lambda m: m.lower(), methods)
def __method_wrapper(f):
this_module = __import__(__name__)
chain = getattr(this_module, f.__name__, method_not_allowed_view)
base_view_func = lambda request, *args, **kwargs: \
f(request, *args, **kwargs) if request.method.lower() in methods \
else chain(request, *args, **kwargs)
setattr(this_module, f.__name__, base_view_func)
return base_view_func
return __method_wrapper
@http_method('get')
def my_view(request):
return HttpResponse("Thank you for GETting.")
@http_method('post', 'put')
def my_view(request):
return HttpResponse("Thank you for POSTing or PUTting.")
# url(r'...', 'app.my_view'),
В любом случае этот пост является вики-страницей сообщества, так что не стесняйтесь улучшать, если вам нравится идея! И история изменений также содержит несколько других подходов, которые я пробовал перед написанием этой статьи ...
m сохраняю это здесь исключительно для исторических целей. Старый текст ответа:В одном конкретном представлении, где мне нужно иметь отдельный код для разных HTTP-методов (это моя крошечная реализация WebDAV), я делаю что-то вроде этого:
class SomeView(object):
def method_get(self, request, ...):
...
def __call__(self, request, *args, **kwargs):
m = getattr(self, 'method_%s' % request.method.lower(), None)
if m is not None:
return m(request, user, *args, **kwargs)
return HttpResponseNotAllowed("405 Method Not Allowed")
# Then url(r'...', SomeView()),
Добавлено / отредактировано: Ну, я немного подумал и реализовал подход декоратора. Это не так плохо, как я первоначально думал.
def method_not_allowed_view(request, *args, **kwargs):
return HttpResponseNotAllowed("405 Method Not Allowed")
def http_method(*methods):
methods = map(lambda m: m.lower(), methods)
def __method_wrapper(f):
this_module = __import__(__name__)
chain = getattr(this_module, f.__name__, method_not_allowed_view)
base_view_func = lambda request, *args, **kwargs: \
f(request, *args, **kwargs) if request.method.lower() in methods \
else chain(request, *args, **kwargs)
setattr(this_module, f.__name__, base_view_func)
return base_view_func
return __method_wrapper
@http_method('get')
def my_view(request):
return HttpResponse("Thank you for GETting.")
@http_method('post', 'put')
def my_view(request):
return HttpResponse("Thank you for POSTing or PUTting.")
# url(r'...', 'app.my_view'),
В любом случае этот пост является вики-страницей сообщества, так что не стесняйтесь улучшать, если вам нравится идея! И история изменений также содержит несколько других подходов, которые я пробовал перед написанием этой статьи ...
m сохраняю это здесь исключительно для исторических целей. Старый текст ответа:В одном конкретном представлении, где мне нужно иметь отдельный код для разных HTTP-методов (это моя крошечная реализация WebDAV), я делаю что-то вроде этого:
class SomeView(object):
def method_get(self, request, ...):
...
def __call__(self, request, *args, **kwargs):
m = getattr(self, 'method_%s' % request.method.lower(), None)
if m is not None:
return m(request, user, *args, **kwargs)
return HttpResponseNotAllowed("405 Method Not Allowed")
# Then url(r'...', SomeView()),
Добавлено / отредактировано: Ну, я немного подумал и реализовал подход декоратора. Это не так плохо, как я первоначально думал.
def method_not_allowed_view(request, *args, **kwargs):
return HttpResponseNotAllowed("405 Method Not Allowed")
def http_method(*methods):
methods = map(lambda m: m.lower(), methods)
def __method_wrapper(f):
this_module = __import__(__name__)
chain = getattr(this_module, f.__name__, method_not_allowed_view)
base_view_func = lambda request, *args, **kwargs: \
f(request, *args, **kwargs) if request.method.lower() in methods \
else chain(request, *args, **kwargs)
setattr(this_module, f.__name__, base_view_func)
return base_view_func
return __method_wrapper
@http_method('get')
def my_view(request):
return HttpResponse("Thank you for GETting.")
@http_method('post', 'put')
def my_view(request):
return HttpResponse("Thank you for POSTing or PUTting.")
# url(r'...', 'app.my_view'),
В любом случае этот пост является вики-страницей сообщества, так что не стесняйтесь улучшать, если вам нравится идея! И история изменений также содержит несколько других подходов, которые я пробовал перед написанием этой статьи ...
Я немного подумал и реализовал подход декоратора. Это не так плохо, как я первоначально думал.def method_not_allowed_view(request, *args, **kwargs):
return HttpResponseNotAllowed("405 Method Not Allowed")
def http_method(*methods):
methods = map(lambda m: m.lower(), methods)
def __method_wrapper(f):
this_module = __import__(__name__)
chain = getattr(this_module, f.__name__, method_not_allowed_view)
base_view_func = lambda request, *args, **kwargs: \
f(request, *args, **kwargs) if request.method.lower() in methods \
else chain(request, *args, **kwargs)
setattr(this_module, f.__name__, base_view_func)
return base_view_func
return __method_wrapper
@http_method('get')
def my_view(request):
return HttpResponse("Thank you for GETting.")
@http_method('post', 'put')
def my_view(request):
return HttpResponse("Thank you for POSTing or PUTting.")
# url(r'...', 'app.my_view'),
В любом случае этот пост является вики-страницей сообщества, так что не стесняйтесь улучшать, если вам нравится идея! И история изменений также содержит несколько других подходов, которые я пробовал перед написанием этой статьи ...
Я немного подумал и реализовал подход декоратора. Это не так плохо, как я первоначально думал.def method_not_allowed_view(request, *args, **kwargs):
return HttpResponseNotAllowed("405 Method Not Allowed")
def http_method(*methods):
methods = map(lambda m: m.lower(), methods)
def __method_wrapper(f):
this_module = __import__(__name__)
chain = getattr(this_module, f.__name__, method_not_allowed_view)
base_view_func = lambda request, *args, **kwargs: \
f(request, *args, **kwargs) if request.method.lower() in methods \
else chain(request, *args, **kwargs)
setattr(this_module, f.__name__, base_view_func)
return base_view_func
return __method_wrapper
@http_method('get')
def my_view(request):
return HttpResponse("Thank you for GETting.")
@http_method('post', 'put')
def my_view(request):
return HttpResponse("Thank you for POSTing or PUTting.")
# url(r'...', 'app.my_view'),
В любом случае этот пост является вики-страницей сообщества, так что не стесняйтесь улучшать, если вам нравится идея! И история изменений также содержит несколько других подходов, которые я пробовал перед написанием этой статьи ...