In my Django project I have a model with just a couple of fields. But there are a lot of related objects: sets of dates, places, comments etc. But its DetailView shows rather a lot of things. So, I decided to update the model via ajax. Django's UpdateView uses redirect to success_url. This seems to be the root of all the troubles.
I used this: https://docs.djangoproject.com/en/1.10/topics/class-based-views/generic-editing/#ajax-example
I checked the update form manually in the browser.
And via ajax the data is also updated on the server. But I can't catch the result via ajax.
In Chrome dev tools while debugging js I occur in fail function. And jqXHR.status=0, textStatus = "error", errorThrown="".
When I switch from Sources tab to Console I can read:
POST http://localhost:8000/frame/2/ 405 (Method Not Allowed)
Could you help me cope with this?
views.py
class FrameUpdate(AjaxableResponseMixin, UpdateView):
model = Frame
form_class = FrameUpdateForm
template_name = "general/ajax/ajax_form.html"
def get_success_url(self):
success_url = reverse_lazy("frame:frame_detail_ajax",
kwargs={"pk":self.object.id})
return success_url
frame.js
function fail(jqXHR, textStatus, errorThrown){
debugger;
}
function post(){
$.ajax({
method: "POST",
url: "http://localhost:8000/frame/2/update/",
data: $("#frame_form").serialize(),
success: show_post,
error: fail
});
}
Added later
photoarchive/urls.py
url(r'^frame/', include('frame.urls', namespace='frame')),
frame/urls.py
url(r'^(?P<pk>\d+)/$', FrameDetailView.as_view(), name="frame_detail"),
url(r'^(?P<pk>\d+)/ajax/$', FrameDetailAjax.as_view(), name="frame_detail_ajax"),
url(r'^(?P<pk>\d+)/update/$', FrameUpdate.as_view(), name="frame_update"),
frame.js
function show_post(data){
debugger;
var frame_form = $("#frame_form");
frame_form.replaceWith(data);
show_controls();
}
general.js
function show_controls(){
var controls = $(".control");
controls.addClass( "show" );
controls.removeClass( "hidden" );
}
Added later
I have decided to start from scratch and make a simulator. The result astonished me.
If I load DetailView, then press AjaxEdit link, then not working.
But if I click Edit link, edit once by without ajax, then AjaxEdit starts working.
By the way, if I remove redefinition of form_valid from the view, nothing works at all (that is editing without ajax don't help).
Could you comment on this?
This is a link to the simulator https://Kifsif@bitbucket.org/Kifsif/ajax_update.git
views.py
class GeneralUpdate(UpdateView):
model = General
fields = ['char']
def form_valid(self, form):
self.object = form.save()
return render(self.request, 'general/general_detail.html', {"object": self.object})
models.py
class General(models.Model):
char = models.CharField(max_length=100)
def get_absolute_url(self):
return reverse("detail", kwargs={"pk": self.id})
urls.py
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^create$', GeneralCreate.as_view(), name="create"),
url(r'^(?P<pk>\d+)/detail$', GeneralDetailView.as_view(), name="detail"),
url(r'^(?P<pk>\d+)/edit$', GeneralUpdate.as_view(), name="edit"),
]
general_form.html
<form id="form" action="" method="post">{% csrf_token %}
{{ form.as_p }}
<input id="submit" type="submit" value="Save" />
</form>
general_detail.html
<p id="char">{{ object.char }}</p>
<a href="{% url "edit" object.id %}">Edit</a>
<a id="ajax_edit" href="javascript:void(0)">AjaxEdit</a>
<script src="https://code.jquery.com/jquery-3.1.0.min.js" integrity="sha256-cCueBR6CsyA4/9szpPfrX3s49M9vUU5BgtiJj06wt/s=" crossorigin="anonymous"></script>
<script>
$( document ).ready(function() {
var ajax_edit = $("#ajax_edit");
var char = $("#char");
function show_get(data){
$(data).insertAfter(char);
var submit_link = $("#submit");
submit_link.click(post);
}
function show_post(data){
debugger;
}
function failure(jqXHR, textStatus, errorThrown){
debugger;
}
function post(){
$.ajax({
method: "post",
data: $("form").serialize(),
url: 'http://localhost:8000/2/edit',
success: show_post,
error: failure,
}
)
}
function get(){
$.ajax({
method: "get",
url: 'http://localhost:8000/2/edit',
success: show_get,
}
)
}
ajax_edit.click(get);
});
</script>