Django class based post-only view
Asked Answered
D

5

30

Sorry if this is a trivial question but I've been searching around for quite sometime and have been unable to find a good implementation.

Can someone provide an example of how to implement a post-only view (that can handle file uploads) in Django by subclassing any of the generic views?

I want to create an endpoint which handles all blog post comment creation logic. The comment form is embedded on my blog page and thus, this data will be sent to the url as POST.

Dianoia answered 26/4, 2016 at 8:39 Comment(0)
R
51

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.

Rare answered 26/4, 2016 at 12:41 Comment(0)
E
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)
Ebberta answered 26/4, 2016 at 8:55 Comment(1)
I used it to avoid formsets in a table with bulk functions (delete, archive). Much simpler and cleaner.Paigepaik
C
4

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.

Camorra answered 26/4, 2016 at 8:50 Comment(3)
This assumes DRF is being usedKurtis
I am guessing there has to be ways to do this by myself. I am using normal views for everything. Using DRF for one particular view seems to be an overkill.Dianoia
@Kurtis Yes it assumed that DRF is used. I have edited the answerCamorra
K
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.

Kurtis answered 26/4, 2016 at 9:2 Comment(1)
hm, I do have TemplateView class and I have post defined but it does not block get requests, it is my intention so no problem with that but your answer got me wondering, maybe it is exception from the rule above since post is blocked until defined for that oneRoderica
Z
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

Zymolysis answered 24/10, 2021 at 3:57 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.