Why the form is not JSON serializable?

久未见 提交于 2020-12-07 06:20:53

问题


I am using Django and I am trying when a button is clicked to get data from the database and fill a form with them through AJAX.

I get the error TypeError: Object of type 'EditProductForm' is not JSON serializablefrom the edit_product_view in my views.py

Below is the code I am working with:

-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'])
        }
    })
}

What happens is that when I click <button onclick="findMyForm({{ product.pk }})">Update product</button> the function findMyForm({{ product.pk }}) runs.

Then a get request is called on '/product/' + productKey + '/edit/' through AJAX, based on the urls.py and views.py, edit_product_view is called to pass the form which is filled with the appropriate data.

At this point, it says that TypeError: Object of type 'EditProductForm' is not JSON serializable. I can't figure it out.


回答1:


The object 'EditProductForm' is not JSON serializable, what you need is to return the form as HTML str, change your views.py:

from

return JsonResponse({'form': form}) 

to

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


来源:https://stackoverflow.com/questions/46396494/why-the-form-is-not-json-serializable

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!