为什么表单不是JSON可序列化的?

时间:2017-09-25 01:41:32

标签: python json ajax django

我正在使用Django,我正在尝试点击按钮从数据库中获取数据并通过AJAX填充表单。

我从TypeError: Object of type 'EditProductForm' is not JSON serializable

中的edit_product_view收到错误views.py

以下是我正在使用的代码:

-urls.py

from django.conf.urls import url
from . import views

app_name = "products"
urlpatterns = [url(r'^products', views.ProductsView.as_view(), name="products"),
               url(r"^product/new", views.add_new_product_view, name="add_new_product"),
               url(r"^product/(?P<id>[0-9]+)/edit/", views.edit_product_view, name="edit_product")]

-views.py

from django.views.generic import DetailView, ListView, TemplateView
from django.http import JsonResponse
from django.shortcuts import render, get_object_or_404
from . import models
from products.forms import AddNewProductForm, EditProductForm


def index(request):
    return render(request, 'products/products.html')


class ProductsView(ListView):
    context_object_name = "products"
    model = models.Product
    template_name = "products/products.html"
    form = AddNewProductForm()

    def get_context_data(self, **kwargs):
        context = super(ProductsView, self).get_context_data(**kwargs)
        context["products"] = models.Product.objects.all().order_by("title")
        context["form"] = self.form
        return context


def add_new_product_view(request):
    if request.method == "POST":
        form = AddNewProductForm(request.POST)
        if form.is_valid():
            form.save(commit=True)
            return JsonResponse({'msg': 'Data saved'})
        else:
            print("ERROR FORM INVALID")
            return JsonResponse({'msg': 'ERROR FORM INVALID'})
    else:
        form = AddNewProductForm()

    return JsonResponse({'form': form})


def edit_product_view(request, id):
    print(request.method)
    instance = get_object_or_404(models.Product, id=id)
    form = EditProductForm(instance=instance)
    if request.method == "POST":
        form = EditProductForm(request.POST, instance=instance)

        if form.is_valid():
            form.save(commit=True)
            return JsonResponse({'form': form})
        else:
            print("ERROR FORM INVALID")

    return JsonResponse({'form': form})

-products.html

{% extends "products/base.html" %}
{% load static %}

{% block title %}My Products{% endblock %}

{% block content %}

   <div class="container" id="my-products-table-container">
        <h2 class="text-left caption">Add, view and edit products</h2>
        <hr>
        <table class="table table-striped table-sm table-bordered" id="my-products-table">
            <thead class="thead-inverse">
                <tr class="head-row">
                    <th>Title</th>
                    <th>Description</th>
                    <th>Year</th>
                    <th>Manufacturer</th>
            </thead>

            <tbody>
                {% for product in products %}
                    <tr class="table-row">
                    <td>{{ product.title }}</td>
                    <td>{{ product.description }}</td>
                    <td>{{ product.year_manufactured }}</td>
                    <td>{{ product.manufacturer }}</td>
                    <td><button type="button" class="btn btn-primary"  data-toggle="modal" data-target="#addNewProductModalForm">Add New product</button></td>
                    <td><button onclick="findMyForm({{ product.pk }})">Update product</button></td>
                {% endfor %}
            </tbody>
        </table>
    </div>
            <!-- Modal Add New Product-->
            <div class="modal fade" id="addNewProductModalForm" tabindex="-1" role="dialog" aria-labelledby="addNewProductModalFormLabel" aria-hidden="true">
              <div class="modal-dialog" role="document">
              <form class="form" id="add_new_product_form">
                    <div class="modal-content">
                      <div class="modal-header">
                        <h5 class="modal-title" id="addNewProductModalFormLabel">Add New Product</h5>
                        <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                          <span aria-hidden="true">&times;</span>
                        </button>
                      </div>
                      <div class="modal-body">
                         {% csrf_token %}
                         {{ form.as_p }}
                      </div>
                      <div class="modal-footer">
                        <button type="button" class="btn btn-secondary" onclick="addNewProduct()">Submit</button>
                      </div>
                    </div>
              </form>
              </div>
            </div>


            <!-- Modal Edit-->
            <div class="modal fade" id="editProductModalForm" tabindex="-1" role="dialog" aria-labelledby="editProductModalFormLabel" aria-hidden="true">
              <div class="modal-dialog" role="document">
              <form class="form"  id="edit_product_form" >
                    <div class="modal-content">
                      <div class="modal-header">
                        <h5 class="modal-title" id="editProductModalFormLabel">Edit Product</h5>
                        <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                          <span aria-hidden="true">&times;</span>
                        </button>
                      </div>
                      <div class="modal-body">
                          {% csrf_token %}
                          <div id='showForm'></div>
                      </div>
                      <div class="modal-footer">
                        <input type="submit" class="btn btn-primary" value="Submit!">
                      </div>
                    </div>
              </form>
              </div>
            </div>


<!-- JS Scripts  -->
<script src="{% static "products/js/addProduct.js" %}"></script>
<script>
    function findMyForm(productKey) {
        $('#editProductModalForm').modal('show');
        $.ajax({
            type: 'GET',
            url: '/product/' + productKey + '/edit/',
            success: function(res) {
            $("#showForm").html(res);
        }
        })}
</script>
{% endblock %}

-addProduct.js

function addNewProduct(e) {
    var addNewProductForm = $("#add_new_product_form");
    $.ajax({
        type: 'POST',
        url: '/product/new/',
        data: addNewProductForm.serialize(),
        success: function(res){
            alert(res['msg'])
        }
    })
}

当我点击<button onclick="findMyForm({{ product.pk }})">Update product</button>函数findMyForm({{ product.pk }})时,会发生什么。

然后在'/product/' + productKey + '/edit/'上通过AJAX调用get请求,基于urls.py调用views.py, edit_product_view来传递填充了相应数据的表单

此时,它说TypeError: Object of type 'EditProductForm' is not JSON serializable。我无法弄清楚。

1 个答案:

答案 0 :(得分:1)

对象&#39; EditProductForm&#39;不是JSON可序列化的,您需要的是return the form as HTML str,更改您的views.py

来自

return JsonResponse({'form': form}) 

return HttpResponse(form.as_p()) # return form as html str