Django How to Implement CRUD (Create Read Update Delete) Using Ajax and Json
CRUD, it stand for Create Read Update Delete.
Models.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | #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" |
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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | #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) |
1 2 3 4 5 6 7 8 | #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' , ) |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | #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/(?P<pk>\d+)/update/$' , views.product_update, name = 'product_update' ), url(r '^products/(?P<pk>\d+)/delete/$' , views.product_delete, name = 'product_delete' ), ] < / pk>< / pk> |
1 2 3 4 5 6 7 8 9 10 11 | #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 ] |
1 2 3 4 5 6 7 8 9 | //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 %} |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | //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> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | //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 %} |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | //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> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | //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> |
1 2 3 4 5 6 7 8 9 10 11 12 | //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 %} |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | //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 %} |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | //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> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | //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); }); |