Декоратор глагола Http для Django?

doc.toString() работает, как и doc.outerHtml().

5
задан tereško 18 May 2013 в 21:51
поделиться

2 ответа

Существуют стандартные встроенные декораторы для запроса определенного метода HTTP или списка разрешенных методов.

См. Код: http://code.djangoproject.com/browser/ django / trunk / django / views / decorators / http.py .

11
ответ дан 18 December 2019 в 06:51
поделиться

Обновленный ответ в 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'),

В любом случае этот пост является вики-страницей сообщества, так что не стесняйтесь улучшать, если вам нравится идея! И история изменений также содержит несколько других подходов, которые я пробовал перед написанием этой статьи ...

9
ответ дан 18 December 2019 в 06:51
поделиться
Другие вопросы по тегам:

Похожие вопросы: