Hello, habrauzer!
Perhaps I have already started
a mid-life crisis , but in the summer I began work on a large Open Source project. However, about it a little later
, when the code will not be ashamed . So, I want to share a number of snippets that I had to write in order to comply with the concept of DRY
Don't Repeat Youself . Therefore I am going to write several articles.
By the way, you can pay attention to
my previous article .
I'll start with the implementation of AJAX.
Just want to make a reservation - not so long ago I found
an example on the junga website for implementing ajax form. As it turned out, I did almost the same thing, but I did it myself and I am satisfied =) Below I will give my example and analyze it.

')
I ask under the cat.
Speaking about the processing of forms in janga, taking into account the appearance of the
django.views.generic module still in release 1.5, one cannot but pay attention to the FormView class. Since all other generic classes for form processing are inherited from it, I chose it as the object of my experiments.
So, let's go:
Backend
The
is_valid (self, form) and
is_invalid (self, form) methods are responsible for processing the return result if the form meets the requirements of
is_valid () and none, respectively. Making our way up the ancestors before
FormMixin, we see the following:
def form_valid(self, form): """ If the form is valid, redirect to the supplied URL. """ return HttpResponseRedirect(self.get_success_url()) def form_invalid(self, form): """ If the form is invalid, re-render the context data with the data-filled form and errors. """ return self.render_to_response(self.get_context_data(form=form))
In the case of the
is_valid () method, only the redirect prevents us. Therefore, we can safely replace this code with the answer we need:
from django.shortcuts import HttpResponse def form_valid(self, form): return HttpResponse('OK')
As a result, we get the
HTTP 200 code at the output, which expects
jquery .
I also allowed myself to peek into the
ModelFormMixin class and add a form save before an answer. The result was a hybrid:
def form_valid(self, form): form.save() return HttpResponse('OK')
In the case of a form error, the answer is somewhat more complicated - we need to return the error dictionary and display them for the user. However, the task is easily performed using the standard form
errors attribute:
import json from django.http import HttpResponseBadRequest def form_invalid(self, form): errors_dict = json.dumps(dict([(k, [e for e in v]) for k, v in form.errors.items()])) return HttpResponseBadRequest(json.dumps(errors_dict))
Ajaxformmixin
So we get the following class:
from django.views.generic import FormView class AjaxFormMixin(FormView): template_name = 'form_ajax.html'
We now have a class that we can safely inherit, like any other type of
Class-based views . The call will look something like this:
from django.contrib.auth.forms import PasswordChangeForm
It can be used as a
CreateView only with the proviso that we
__init __ () method of the parent class
FormMixin does not accept the model argument and we will have to do this work ourselves:
from django.forms.models import modelform_factory class TaskUserAssign(AjaxFormMixin): form_class = modelform_factory(models.TaskRole)
AjaxUpdateFormMixin
So, we have a base class for handling ajax forms. Why not follow the
django-way and create for one more
generic “in the image and likeness” for the update. In the same
django.views.generic module
, we find the
UpdateView class and the answer for us — we need the
object attribute for our class ... Voila:
class AjaxUpdateFormMixin(AjaxFormMixin, UpdateView): def get(self, request, *args, **kwargs): self.object = self.get_object() return super(AjaxFormMixin, self).get(request, *args, **kwargs) def post(self, request, *args, **kwargs): self.object = self.get_object() return super(AjaxFormMixin, self).post(request, *args, **kwargs)
Without a doubt, we copy the code, only we inherit everything else from the
AjaxFormMixin class that we already have. By the way, this class already has the model attribute, since we inherited it from
UpdateView , whose roots go to
ModelFormMixin .
As a result, we have a set of classes that support creating, modifying objects and other actions with them (redefine
is_valid () as well as
/ dev / brain and
/ dev / hands to taste) with ajax answers for free,
not prohibited by law inheritance.
PS The purpose of the article was not so much in demonstrating my achievements (although what is there to be cunning), but in the analysis of the process itself. A little later, when my assistant completes the code for the application's muzzle, we will supplement the article with the front-end component code. In the meantime, thank you all for your attention.