2
Django forms and formsets are intended for classic browser-based posting of data. Though they can definitely be made to work with Javascript, the more you want to part from the normal behavior, the more complex it gets.
Depending on your requirements, you might start thinking about dropping it and switch to Javascript + REST endpoint. Of course, if you need progressive enhancements and you are required to have it work without javascript, that’s not an option.
In any case, you want to have a customized view for posting from JS, so that you can get the result back and parse it easily in your AJAX handler. Probably some JSON.
There are several approaches you could take.
-
Have your AJAX send data to a different URL. This is pertinent if you have an API or are planning to build one at some point. So your form, when submitted normally, will do its old-style processing but your AJAX will talk to the API endpoint instead.
For instance, your form send to
https://example.com/myform
, but your Javascript code talks to REST api athttps://example.com/api/v1/mymodel/
(sending PUT, POST and DELETE requests as appropriate). -
Or if you don’t have an API and building one seems overkill, you may just alter your view so it formats its output differently depending on whether the data is being submitted in the regular way or using AJAX.
You’d go about it like this:
class MyFormView(.....): def render_to_response(self, context, **kwargs): if self.request.is_ajax(): return self.render_to_json(context, **kwargs) return super().render_to_response(context, **kwargs) def render_to_json(context, **kwargs): data = { # see below! } return HttpResponse( content=json.dumps(data).encode('ascii'), content_type='application/json', )
This is just an outline. You need to ensure
is_ajax
will detect it properly (see django doc). And you need to properly builddata
fromcontext
: extract the things you want to send back to your JS code and put them in the dict.You will find it’s manageable if you just do this for one, maybe two views in your project, but very quickly you’ll want to have a small API instead, especially given how easy it is to build one with packages such as Django REST framework.
0
In your view, where you save the object, AFTER the save, the object.id will contain the new id for the object, which you can return via json or however you want in your ajax response, and then yes you will need to fill that into the formset row so that it will be submitted the next time.
One thing you have to watch out for is that django expects all existing rows to be at the top of the formset, and any new rows to be at the bottom. Otherwise, the formset save will complain about missing id’s. So if you’re doing any kind of sorting in your javascript, you can’t do that.. unless you do quite a bit of fixing of all the field names etc in the formset. The formset code uses the numbers in the management form to determine which rows to insert and which rows to update, it does not do it on the basis of whether or not an id is present. Unfortunately…
- [Answered ]-How to pass values for password_reset() in Django 1.10?
- [Answered ]-How to specify authentication info to memcache with django?