I have a written a mixin that overrides the POST
and get_from_kwargs
of CreateView
. I am doing AJAX
submission of my form. I see that get_from_kwargs
is called by printing on the console. But none of the other methods such as post
,form_valid
or form_invalid
is being called. I have placed print statements in these methods but none of them is being called.
Here is my mixin:
class PendFormMixin(object):
form_hash_name = 'form_hash'
pend_button_name = 'pend'
def get_form_kwargs(self):
"""
Returns a dictionary of arguments to pass into the form instantiation.
If resuming a pended form, this will retrieve data from the database.
"""
pk_form = self.kwargs.get('pk', None)
form_hash = None
if pk_form:
form_data = PendedForm.objects.get(pk=pk_form)
form_hash = form_data.hash
print "form_hash", form_hash
if form_hash:
import_path = self.get_import_path(self.get_form_class())
print import_path
print self.get_pended_data(import_path, form_hash)
return {'data': self.get_pended_data(import_path, form_hash)}
else:
print "called in kwargs"
# print super(PendFormMixin, self).get_form_kwargs()
return super(PendFormMixin, self).get_form_kwargs()
def post(self, request, *args, **kwargs):
"""
Handles POST requests with form data. If the form was pended, it doesn't follow
the normal flow, but saves the values for later instead.
"""
self.object = None
if self.pend_button_name in self.request.POST:
print "here"
form_class = self.get_form_class()
print form_class
form = self.get_form(form_class)
# print "form is ", form
self.form_pended(form)
return super(PendFormMixin, self).post(request, *args, **kwargs)
else:
print "here in post"
return super(PendFormMixin, self).post(request, *args, **kwargs)
# Custom methods follow
def get_import_path(self, form_class):
return '{0}.{1}'.format(form_class.__module__, form_class.__name__)
def get_form_hash(self, form):
content = ','.join('{0}:{1}'.format(n, form.data[n]) for n in form.fields.keys())
return md5(content).hexdigest()
def form_pended(self, form):
import_path = self.get_import_path(self.get_form_class())
form_hash = self.get_form_hash(form)
pended_form = PendedForm.objects.get_or_create(form_class=import_path,
hash=form_hash)
for name in form.fields.keys():
pended_form[0].data.get_or_create(name=name, value=form.data[name])
return form_hash
def get_pended_data(self, import_path, form_hash):
print "import_path is", import_path
print "form_hash is", form_hash
# data = PendedValue.objects.filter(import_path=import_path, form_hash=form_hash)
data = PendedValue.objects.filter(form__form_class=import_path, form__hash=form_hash)
print "data ", data
return dict((d.name, d.value) for d in data)
Here is my view:
class ArticleCreateView(PendFormMixin, CreateView):
form_class = ArticleForm
model = Article
template_name = "article_create.html"
# success_url = reverse_lazy('blog_create')
success_url = '/admin'
def form_valid(self, form):
"""
If the request is ajax, save the form and return a json response.
Otherwise return super as expected.
"""
if self.request.is_ajax():
self.object = form.save()
time.sleep(5)
print "here"
return HttpResponse(json.dumps("success"),
mimetype="application/json")
if self.pend_button_name in self.request.POST:
print "in the form_valid"
return
print "in the form_valid"
return super(ArticleCreateView, self).form_valid(form)
def form_invalid(self, form):
"""
We haz errors in the form. If ajax, return them as json.
Otherwise, proceed as normal.
"""
print "self is ", self.request.POST
if self.request.is_ajax():
return HttpResponseBadRequest(json.dumps(form.errors),
mimetype="application/json")
if self.pend_button_name in self.request.POST:
print "in the form_invalid"
return redirect('/admin')
return super(ArticleCreateView, self).form_invalid(form)
unable to figureout what is going wrong. It used to work previously, before I used the mixin. but by introducing the above mixin, the code does not work any more.