Django How to Implement CRUD (Create Read Update Delete) Using Ajax and Json
CRUD, it stand for Create Read Update Delete.
Models.py
#models.py from django.db import models class Product(models.Model): FILLOW = 1 FOOD = 2 TOYS = 3 PRODUCT_TYPES = ( (FILLOW, 'Pillow'), (FOOD, 'Food'), (TOYS, 'Toys'), ) name = models.CharField(max_length=50) dateadded = models.DateField(blank=True, null=True) productcode = models.CharField(max_length=30, blank=True) price = models.DecimalField(max_digits=5, decimal_places=2) quantity = models.IntegerField(blank=True, null=True) category_type = models.PositiveSmallIntegerField(choices=PRODUCT_TYPES, blank=True, null=True) class Meta: db_table = "myapp_product"Database Table
CREATE TABLE myapp_product (
id INTEGER PRIMARY KEY,
name STRING (200),
productcode STRING (150),
price INTEGER,
quantity INTEGER,
category_type STRING (50),
dateadded DATE
);
Views.py
#views.py from django.shortcuts import render, redirect, get_object_or_404 from myapp.models import Product from myapp.forms import ProductForm from django.http import JsonResponse from django.template.loader import render_to_string def index(request): return render(request, 'index.html') def product_list(request): products = Product.objects.all() return render(request, 'product_list.html', {'products': products}) def save_product_form(request, form, template_name): data = dict() if request.method == 'POST': if form.is_valid(): form.save() data['form_is_valid'] = True products = Product.objects.all() data['html_product_list'] = render_to_string('includes/partial_product_list.html', { 'products': products }) else: data['form_is_valid'] = False context = {'form': form} data['html_form'] = render_to_string(template_name, context, request=request) return JsonResponse(data) def product_create(request): if request.method == 'POST': form = ProductForm(request.POST) else: form = ProductForm() return save_product_form(request, form, 'includes/partial_product_create.html') def product_update(request, pk): product = get_object_or_404(Product, pk=pk) if request.method == 'POST': form = ProductForm(request.POST, instance=product) else: form = ProductForm(instance=product) return save_product_form(request, form, 'includes/partial_product_update.html') def product_delete(request, pk): product = get_object_or_404(Product, pk=pk) data = dict() if request.method == 'POST': product.delete() data['form_is_valid'] = True products = Product.objects.all() data['html_product_list'] = render_to_string('includes/partial_product_list.html', { 'products': products }) else: context = {'product': product} data['html_form'] = render_to_string('includes/partial_product_delete.html', context, request=request) return JsonResponse(data)forms.py
#forms.py from django import forms from myapp.models import Product class ProductForm(forms.ModelForm): class Meta: model = Product fields = ('name', 'dateadded', 'productcode', 'price', 'quantity', 'category_type', )urls.py
#urls.py from django.contrib import admin from django.urls import path from myapp import views from django.conf.urls import url urlpatterns = [ path('admin/', admin.site.urls), path('',views.index), url(r'^products/$', views.product_list, name='product_list'), url(r'^create/$', views.product_create, name='product_create'), url(r'^products/(?Psettings.py pip install django-widget-tweaks\d+)/update/$', views.product_update, name='product_update'), url(r'^products/(?P \d+)/delete/$', views.product_delete, name='product_delete'), ]
#settings.py INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'myapp', 'widget_tweaks', #pip install django-widget-tweaks ]
//templates/index.html {% extends 'base.html' %} {% block content %} <h1 class="page-header">Django How to Implement CRUD (Create Read Update Delete) Using Ajax and Json</h1> <p class="lead">See the example clicking in the Product menu.</p> <p class="lead"><a href="/products">Product List</a>.</p> {% endblock %}
//templates/base.html <!DOCTYPE html> <html lang="en"> <head> {% load static %} <link rel="stylesheet" type="text/css" href="{% static 'css/bootstrap.css' %}"/> <meta charset="UTF-8" name="viewport" content="width=device-width, initial-scale=1"/> <title>{% block title %}Django How to Implement CRUD (Create Read Update Delete) Using Ajax and Json{% endblock %}</title> <link href="{% static 'css/bootstrap.min.css' %}" rel="stylesheet"> </head> <body> <nav class="navbar navbar-default"> <div class="container-fluid"> <a class="navbar-brand">Cairocoders</a> </div> </nav> <div class="container"> <div class="col-md-12 well"> <h3 class="text-primary">Django How to Implement CRUD (Create Read Update Delete) Using Ajax and Json</h3> <hr style="border-top:1px dotted #ccc;"/> {% block content %} {% endblock %} </div> </div> <script src="{% static 'js/jquery-3.1.1.min.js' %}"></script> <script src="{% static 'js/bootstrap.min.js' %}"></script> {% block javascript %} {% endblock %} </body> </html>
//templates/product_list.html {% extends 'base.html' %} {% load static %} {% block javascript %} <script src="{% static 'js/script.js' %}"></script> {% endblock %} {% block content %} <h1 class="page-header">Products</h1> <p> <button type="button" class="btn btn-primary js-create-product" data-url="{% url 'product_create' %}"> <span class="glyphicon glyphicon-plus"></span> New Product </button> </p> <table class="table" id="product-table"> <thead> <tr> <th>#</th> <th>Name</th> <th>Date Added</th> <th>Category</th> <th>Product Code</th> <th>Quantiry</th> <th>Price</th> <th></th> </tr> </thead> <tbody> {% include 'includes/partial_product_list.html' %} </tbody> </table> <div class="modal fade" id="modal-product"> <div class="modal-dialog"> <div class="modal-content"> </div> </div> </div> {% endblock %}
//templates/includes/partial_product_create.html <form method="post" action="{% url 'product_create' %}" class="js-product-create-form"> {% csrf_token %} <div class="modal-header"> <button type="button" class="close" data-dismiss="modal" aria-label="Close"> <span aria-hidden="true">×</span> </button> <h4 class="modal-title">Create a new product</h4> </div> <div class="modal-body"> {% include 'includes/partial_product_form.html' %} </div> <div class="modal-footer"> <button type="button" class="btn btn-default" data-dismiss="modal">Close</button> <button type="submit" class="btn btn-primary">Create product</button> </div> </form>
//templates/includes/partial_product_delete.html <form method="post" action="{% url 'product_delete' product.id %}" class="js-product-delete-form"> {% csrf_token %} <div class="modal-header"> <button type="button" class="close" data-dismiss="modal" aria-label="Close"> <span aria-hidden="true">×</span> </button> <h4 class="modal-title">Confirm product deletion</h4> </div> <div class="modal-body"> <p class="lead">Are you sure you want to delete the product <strong>{{ product.name }}</strong>?</p> </div> <div class="modal-footer"> <button type="button" class="btn btn-default" data-dismiss="modal">Close</button> <button type="submit" class="btn btn-danger">Delete product</button> </div> </form>
//templates/includes/partial_product_form.html {% load widget_tweaks %} {% for field in form %} <div class="form-group{% if field.errors %} has-error{% endif %}"> <label for="{{ field.id_for_label }}">{{ field.label }}</label> {% render_field field class="form-control" %} {% for error in field.errors %} <p class="help-block">{{ error }}</p> {% endfor %} </div> {% endfor %}
//templates/includes/partial_product_list.html {% for product in products %} <tr> <td>{{ product.id }}</td> <td>{{ product.name }}</td> <td>{{ product.dateadded }}</td> <td>{{ product.get_category_type_display }}</td> <td>{{ product.productcode }}</td> <td>{{ product.quantity }}</td> <td>{{ product.price }}</td> <td style="width: 150px"> <button type="button" class="btn btn-warning btn-sm js-update-product" data-url="{% url 'product_update' product.id %}"> <span class="glyphicon glyphicon-pencil"></span> Edit </button> <button type="button" class="btn btn-danger btn-sm js-delete-product" data-url="{% url 'product_delete' product.id %}"> <span class="glyphicon glyphicon-trash"></span> Delete </button> </td> </tr> {% empty %} <tr> <td colspan="8" class="text-center bg-warning">No product</td> </tr> {% endfor %}
//templates/includes/partial_product_update <form method="post" action="{% url 'product_update' form.instance.pk %}" class="js-product-update-form"> {% csrf_token %} <div class="modal-header"> <button type="button" class="close" data-dismiss="modal" aria-label="Close"> <span aria-hidden="true">×</span> </button> <h4 class="modal-title">Update product</h4> </div> <div class="modal-body"> {% include 'includes/partial_product_form.html' %} </div> <div class="modal-footer"> <button type="button" class="btn btn-default" data-dismiss="modal">Close</button> <button type="submit" class="btn btn-primary">Update product</button> </div> </form>
//static/js/script.js $(document).ready(function(){ var loadForm = function () { var btn = $(this); $.ajax({ url: btn.attr("data-url"), type: 'get', dataType: 'json', beforeSend: function () { $("#modal-product .modal-content").html(""); $("#modal-product").modal("show"); }, success: function (data) { $("#modal-product .modal-content").html(data.html_form); } }); }; var saveForm = function () { var form = $(this); $.ajax({ url: form.attr("action"), data: form.serialize(), type: form.attr("method"), dataType: 'json', success: function (data) { if (data.form_is_valid) { $("#product-table tbody").html(data.html_product_list); $("#modal-product").modal("hide"); } else { $("#modal-product .modal-content").html(data.html_form); } } }); return false; }; /* Binding */ $(".js-create-product").click(loadForm); $("#modal-product").on("submit", ".js-product-create-form", saveForm); // Update product $("#product-table").on("click", ".js-update-product", loadForm); $("#modal-product").on("submit", ".js-product-update-form", saveForm); // Delete product $("#product-table").on("click", ".js-delete-product", loadForm); $("#modal-product").on("submit", ".js-product-delete-form", saveForm); });