[Django]-Django class based post-only view

49πŸ‘

βœ…

The View class has an http_method_names attribute that lists the HTTP methods that the view will accept.

Therefore, you could subclass any generic view you like (for example, CreateView), and set http_method_names so that only POST requests are allowed.

from django.views.generic.edit import CreateView


class CommentCreateView(CreateView):
    http_method_names = ['post']
    model = Comment
    ...

Alternatively, you could subclass View, and write your own post method.

class CommentView(View):

    def post(self, request):
        ...

In this case, GET requests will return a HttpResponseNotAllowed response, because you have not defined a get method to handle GET requests.

πŸ‘€Alasdair

8πŸ‘

You could try something like:

class MyView(TemplateView):
    template_name = 'my_template.html'

    def post(self, request, **kwargs):
        my_data = request.POST
        # do something with your data
        context = {}  #  set your context
        return super(TemplateView, self).render_to_response(context)

4πŸ‘

From the docs:

dispatch looks at the request to determine whether it is a GET, POST, etc, and relays the request to a matching method if one is defined, or raises HttpResponseNotAllowed

So essentially, any class based view you create where you only define a POST method, will only allow a POST request.

πŸ‘€Sayse

3πŸ‘

I guess something like this should work:

class TestView(View):

    def post(self, request):
        return HttpResponse('This is a post only view')

You can also do this by using a CreateAPIView if you use Django Rest Framework
http://www.django-rest-framework.org/api-guide/generic-views/#createapiview

Used for create-only endpoints.

Provides a post method handler.

πŸ‘€Ankur Gupta

3πŸ‘

There is a built-in decorator for that: require_POST(). More generically, you can use require_http_methods().

For function-based views (copied from the documentation):

from django.views.decorators.http import require_http_methods

@require_http_methods(["GET", "POST"])
def my_view(request):
    # I can assume now that only GET or POST requests make it this far
    # ...
    pass

For class-based views:

from django.utils.decorators import method_decorator
from django.views.decorators.http import require_http_methods

@method_decorator(require_http_methods(["GET", "POST"]), name='dispatch')
class MyView(View):
    # I can assume now that only GET or POST requests make it this far
    # ...
    pass

πŸ‘€Bartleby

Leave a comment