带有CBV Django的AJAX表单赞成Form_Invalid Response但仍然发布到DB

时间:2017-07-18 20:09:07

标签: jquery python ajax django

基本上,我有一个只有一个字段的简单表单,需要一个字符串< 200个字符。表单是通过AJAX请求提交的,响应应该保持在同一页面(“drug_new”)并返回成功或失败,并提供有关提交给数据库的详细信息。

实际发生的是:

  

POST http://localhost:8000/drug/new/ 400(错误请求)

服务器日志显示以下内容:

[18/Jul/2017 12:53:35] "GET /drug/new/ HTTP/1.1" 200 3909
invalid loop
[18/Jul/2017 12:53:37] "POST /drug/new/ HTTP/1.1" 400 37
[18/Jul/2017 12:53:37] "POST /drug/new/ HTTP/1.1" 302 0
[18/Jul/2017 12:53:38] "GET /drug/new/ HTTP/1.1" 200 3909

不知何故,数据也会在数据库级别发布,那么是什么呢?我认为它可能与在ajax请求的数据部分中包含csrftokenmiddleware有关,但是当我尝试排除它时,它会导致错误500.我知道我可以使用基于函数的视图来验证表单数据,但我不希望有相同视图的CBV和函数。必须有一种方法可以让CBV使用ajax请求。提前致谢! :d

以下是相关文件:

models.py

class Drug(models.Model):
    #drug_barcode = models.ForeignKey('expirations.Barcode', related_nam='barcodes')
    name = models.CharField(max_length= 200)

    # def get_absolute_url(self):
    #     return reverse('drug_list')

    def __unicode__(self):
        return self.name

    def early_exp(self):
        return self.expiration_dates.all().aggregate(Min('expirationDate')).values()[0]

forms.py

class DrugForm(forms.ModelForm):

    class Meta:
        model = Drug
        fields = ('name',)

views.py

class AjaxableResponseMixin(object):
    def form_valid(self, form):
        response = super(AjaxableResponseMixin, self).form_valid(form)
        if self.request.is_ajax():
            print('valid loop')
            data = {
                'pk': self.object.pk,
                }
            return JsonResponse(data)
        else:
            return response

    def form_invalid(self, form):
        response = super(AjaxableResponseMixin, self).form_invalid(form)
        if self.request.is_ajax():
            print('invalid loop')
            return JsonResponse(form.errors, status=400)
        else:
            return response

class CreateDrugView(AjaxableResponseMixin, CreateView):
    redirect_field_name = reverse_lazy('drug_list')
    form_class = DrugForm

    model = Drug

    def get_success_url(self):
        return reverse_lazy('drug_new')

urls.py

from django.conf.urls import url, include
from django.contrib import admin
from . import views as exp_view

urlpatterns = [
    # url(r'^$', exp_view.home, name = 'home'),
    url(r'^$', exp_view.DrugListView.as_view() , name = 'drug_list'),
    url(r'^list/$', exp_view.DrugExpListView.as_view() , name = 'drug_exp_list'),
    url(r'^drug/new/$',exp_view.CreateDrugView.as_view(), name = 'drug_new'),
]

drug_form.html

{% block content %}
<div class = "container">
    <h1>New Drug</h1>

    <form id="drug_form_id" method="POST" class="post-form">
    {% csrf_token %}
    {{form.as_p}}
    <button id = "submit_drug" type="submit" class="btn btn-primary">Save</button>
    </form>
</div>
{% endblock %}
{% block javascript %}
<script>
$(document).ready(function(){
  var frm = $("#drug_form_id")
    frm.submit(function () {
      console.log(frm.val());
      $.ajax({
        type:"POST",
        url: frm.attr('action'),
        data: {'form':frm.serialize() , 'csrfmiddlewaretoken': '{{ csrf_token }}'},
        success: function(data){
          console.log(data);
        }
      })
    });
})
</script>

{% endblock %}

2 个答案:

答案 0 :(得分:1)

您需要序列化ajax数据的表单数据。即。

$.ajax({
    url: url,
    data: $('#yourForm').serialize(); // Or $(this).serialize() if inside a .submit() function
});

答案 1 :(得分:0)

需要一些mod,但感谢Cory,我能够找到一种方法,使用以下函数调用使其工作:

$(document).ready(function(){
  var frm = $("#drug_form_id")
    frm.submit(function(e) {
      e.preventDefault();
      console.log(frm.serialize());
      $.ajax({
        type:"POST",
        url: "{% url 'drug_new' %}",
        data: $(this).serialize(),
        success: function(data){
          console.log(data);
        }
      })
    });
})