0

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 Answer 1

3

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
Sign up to request clarification or add additional context in comments.

1 Comment

Do you know how I can take the pk from the form so I call the edit_product_view and saved the updated product to the database ?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.