Reputation: 476
I am writing a FormView
which will add for example a comment on Person
object.
I want to check if current user wrote a comment for this Person
and if he did I'd like to raise Http404
.
Question: What is the best place for this validation? I don't want to call validation in get_context_data
and form_valid
. Is dispatch
method a good place for this logic?
Upvotes: 0
Views: 580
Reputation: 53998
Remember that form_valid
will only be called when you POST the form so that won't work as GET requests will still render. You could therefore put it in the get
method for the FormView
which would prevent the view and template loading the initial form. The drawback is that people could technically still POST to that URL if they really wanted to.
As you mentioned, I would put it in the dispatch
method. It is very early in the cycle of the FormView
so you avoid unnecessary processing.
def dispatch(self, request, *args, **kwargs):
# I'm just guessing your Comment/Person models
user = self.request.user
try:
person = Person.objects.get(user=self.request.user)
except:
raise Http404("No user exists")
if Comment.objects.filter(content_object=person).exist():
raise Http404("Comment already exists")
return super(MyFormView, self).dispatch(request, *args, **kwargs)
Upvotes: 2
Reputation: 301
I wrote this mixin
class PermissionCheckMixin(object):
def __init__(self, perm=None, obj=None):
self.perm = perm
self.obj = obj
def dispatch(self, request, *args, **kwargs):
if request.user.is_anonymous():
if request.is_ajax():
return JSONResponseForbidden()
else:
return HttpResponseForbidden()
elif request.user.is_authenticated():
if self.perm:
if request.user.has_perm(self.perm, self.obj):
return super(PermissionCheckMixin, self).dispatch(request, *args, **kwargs)
else:
if request.is_ajax():
return JSONResponseForbidden()
else:
return HttpResponseForbidden()
else:
if request.is_ajax():
return JSONResponseForbidden()
else:
return HttpResponseForbidden()
And use it like this:
class TestFormView(PermissionCheckMixin, FormView):
...
You can easily adapt this mixin, somehow like this:
def __init__(self, pk):
self.person_pk = pk
def dispatch(self, request, *args, **kwargs):
if request.user.is_authenticated():
if request.user.pk == self.person_pk:
return HttpResponseNotFound()
Upvotes: 1