1、ajax簡單介紹
瀏覽器向網站發送請求時 是以URL和表單的形式提交的post 或get 請求,特點是:頁面刷新
除此之外,也可以基于ajax向后臺發送請求(異步)
依賴jQuery
編寫ajax代碼
$.ajax({url: "發送的地址" ,type: "post",data:{n1:123,n2:456 },success:function(res){} }
)
2、在django 使用中了解的知識點
1、在django 中使用ajax發送post請求,通過下面方法免除csrf_token
from django.shortcuts import render,redirect,HttpResponse
from django.views.decorators.csrf import csrf_exempt@csrf_exempt
def task_ajax(request):return HttpResponse('hhhh')
2、想要去數據庫中獲取數據時:可以是對象也可以是字典
# 對象,當前行的所有數據
row_object = models.Order.objects.filter(id=uid).first()
row_object.id
row_object.title
也可以直接獲取字典
# 字典,{"id":1,"title":"xxx"}
row_dict = models.Order.objects.filter(id=uid).values("id","title").filter()
# 列表 [obj,obj,obj]
queryset = models.Order.objects.all()
# [{"id":1,"title":"xxx"},{"id":1,"title":"xxx"},{"id":1,"title":"xxx"}]
queryset = models.Order.objects.all().values("id","title")# queryset = [(1,"xx"),(2,"xx")]
queryset = models.Order.objects.all().values_list("id","title")
3、在django中有一個庫可以實現json序列化,簡化代碼
from django.http import JsonResponsedef order_delete(request):"""刪除訂單"""uid = request.GET.get('uid')exists = models.Order.objects.filter(id=uid).exists()if not exists:return JsonResponse({"status": False, "error": "數據不存在"})models.Order.objects.filter(id=uid).delete()return JsonResponse({"status": True})
3、示例,使用ajax 實現訂單功能的增刪改查
1、 定義訂單表,在models.py中,定義表結構
from django.db import modelsclass Admin(models.Model):username = models.CharField(verbose_name="用戶名",max_length=16)passwd = models.CharField(verbose_name="密碼",max_length=64)def __str__(self):return self.usernameclass Order(models.Model):"""訂單表"""oid = models.CharField(verbose_name='訂單id',max_length=64)title = models.CharField(verbose_name='商品名稱',max_length=32)price = models.DecimalField(verbose_name="價格",max_digits=10,decimal_places=2)status_choice = ((1,"待支付"),(2,"已支付"),)status = models.SmallIntegerField(verbose_name='狀態',choices=status_choice,default=1)admin = models.ForeignKey(verbose_name="用戶",to=Admin,on_delete=models.CASCADE)
2、定義路由,在urls.py中寫接口路徑
from django.urls import path
from app01.views import user,depart,pretty,admin,account,orderurlpatterns = [path('order/list/',order.order_list),path('order/add/',order.order_add),path('order/delete/',order.order_delete),path('order/detail/',order.order_detail),path('order/edit/',order.order_edit),
]
3、實現接口函數,在order.py中實現不同功能的函數
- 列表展示 (查詢)
from django.shortcuts import render
from datetime import datetime
import random
from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt
from app01 import models
from app01.utils.bootstrap import BootStrapModelForm
from app01.utils.pagination import Paginationclass OrderModelForm(BootStrapModelForm):class Meta:model = models.Order#fields = "__all__"# 排除的字段exclude = ['oid','admin']#fields = ['oid','title','price']def order_list(request):queryset = models.Order.objects.all().order_by('-id')page_obj = Pagination(request, queryset)form = OrderModelForm()context = {"form" : form,"queryset": page_obj.page_queryset, # 分完頁的數據"page_string": page_obj.html() # 生成頁碼}return render(request,'order_list.html',context)
這里使用到了分頁的方法,分頁方法如下:
"""
自定義的分頁組件,以后如果想要使用這個分頁組件,你需要做的如下幾件事:在視圖函數 views.oy中def pretty_list(request):# 1、根據自己的情況去篩選自己的數據queryset = models.PrettyNum.objects.all()# 2、實例化分頁對象page_obj = Pagination(request,queryset)context={"search_data": search_data,"queryset": page_obj.page_queryset, #分完頁的數據"page_string":page_obj.html() #生成頁碼}return render(request,'pretty_list.html',context)在html 頁面中<nav aria-label="Page navigation"><ul class="pagination">{{ page_string }}</ul></nav>"""
from django.utils.safestring import mark_safe
import copy
class Pagination():def __init__(self,request,queryset,page_size=10,page_param="page",plus=5):""":param request: 請求的對象:param queryset: 符合條件的數據(根據這個數據庫給他鏡像分頁處理):param page_size: 每頁顯示多少條數據:param page_param: 在URL中傳遞的獲取分頁的參數,例如 /pretty/list/?page=12:param plus: 顯示當前頁的前或后幾頁(頁碼)"""query_dict = copy.deepcopy(request.GET)query_dict._mutable = Trueself.query_dict = query_dictpage = request.GET.get(page_param,"1")if page.isdecimal():page = int(page)else:page = 1self.page = pageself.page_size = page_sizeself.start = (page-1)* page_sizeself.end = page * page_sizeself.page_queryset = queryset[self.start:self.end]total_count = queryset.count()total_page_count,div = divmod(total_count,page_size)if div:total_page_count += 1self.total_page_count = total_page_countself.plus = plusself.page_param = page_paramdef html(self):#計算出,顯示當前頁的前5頁,后5頁if self.total_page_count <= 2 * self.plus + 1:#數據庫中的數據比較少,沒有11頁start_page = 1end_page = self.total_page_countelse:# 數據庫中的數據比較多,大于11頁# 當前頁<5時,(小級值)if self.page <= self.plus:start_page = 1end_page = 2 * self.plus + 1else:# 當前頁大于5#當前頁 + 5 > 總頁面if (self.page + self.plus) > self.total_page_count:start_page = self.total_page_count - 2*self.plusend_page = self.total_page_countelse:start_page = self.page - self.plusend_page = self.page + self.plus# 頁碼page_str_list = []self.query_dict.setlist(self.page_param,[1])page_str_list.append('<li><a href="?{}">首頁</a></li>'.format(self.query_dict.urlencode()))# 上一頁if self.page > 1:self.query_dict.setlist(self.page_param, [self.page -1])prev = '<li><a href="?{}">上一頁</a></li>'.format(self.query_dict.urlencode())else:self.query_dict.setlist(self.page_param, [1])prev = '<li><a href="?{}">上一頁</a></li>'.format(self.query_dict.urlencode())page_str_list.append(prev)#頁面for i in range(start_page,end_page + 1):if i == self.page:self.query_dict.setlist(self.page_param, [i])ele = '<li class="active"><a href="?{}">{}</a></li>'.format(self.query_dict.urlencode(),i)else:self.query_dict.setlist(self.page_param, [i])ele = '<li><a href="?{}">{}</a></li>'.format(self.query_dict.urlencode(), i)page_str_list.append(ele)# 下一頁if self.page < self.total_page_count:self.query_dict.setlist(self.page_param, [self.page + 1])prev = '<li><a href="?{}">下一頁</a></li>'.format(self.query_dict.urlencode())else:self.query_dict.setlist(self.page_param, [self.total_page_count])prev = '<li><a href="?{}">下一頁</a></li>'.format(self.query_dict.urlencode())page_str_list.append(prev)# 尾頁self.query_dict.setlist(self.page_param, [self.total_page_count])page_str_list.append('<li><a href="?{}">尾頁</a></li>'.format(self.query_dict.urlencode()))search_string = """<li><form style="float:left; margin-left: -1px" method="get"><input name="page" style="position: relative;float: left;display: inline-block;width: 80px;border-radius: 0" type="text" class="form-control" placeholder="頁碼"><button style="border-radius: 0" class="btn btn-default" type="submit">跳轉</button></form></li>"""page_str_list.append(search_string)page_string = mark_safe("".join(page_str_list))return page_string
- 訂單的創建
@csrf_exempt
def order_add(request):"""創建訂單,ajax請求"""form = OrderModelForm(data=request.POST)if form.is_valid():#保存數據之前生成oidform.instance.oid = datetime.now().strftime("%Y%m%d%H%M%S") + str(random.randint(1000,9999))# 創建訂單的用戶為當前登錄的用戶,可以取session中獲取當前登錄用戶的信息form.instance.admin_id = request.session["info"]["id"]form.save()return JsonResponse({'status':True})return JsonResponse({"status":False, "error": form.errors})
- 訂單的刪除
def order_delete(request):"""刪除訂單"""uid = request.GET.get('uid')exists = models.Order.objects.filter(id=uid).exists()if not exists:return JsonResponse({"status": False, "error": "數據不存在"})models.Order.objects.filter(id=uid).delete()return JsonResponse({"status": True})
- 根據id 查詢訂單信息
def order_detail(request):"""編輯獲取當前行信息"""uid = request.GET.get('uid')row_dict = models.Order.objects.filter(id=uid).values("id", "title","status","price").first()if not row_dict:return JsonResponse({"status": False, "error": "數據不存在"})result = {"status": True,"data": row_dict}return JsonResponse(result)
- 編輯訂單
@csrf_exempt
def order_edit(request):"""編輯訂單"""uid = request.GET.get('uid')row_object = models.Order.objects.filter(id=uid).first()if not row_object:return JsonResponse({"status": False, "msg": "數據不存在"})form = OrderModelForm(data=request.POST,instance=row_object)if form.is_valid():form.save()return JsonResponse({'status': True})return JsonResponse({"status": False, "error": form.errors})
4、前端頁面的實現order_list.html
{% extends 'layout.html' %}{% block content %}<div class="container"><div><input id="btnAdd" type="button" class="btn btn-primary" value="新建訂單1"></div></div><div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel"><div class="modal-dialog" role="document"><div class="modal-content"><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" id="myModalLabel">新 建</h4></div><div class="modal-body"><form id="formAdd"><div class="clearfix">{% for field in form %}<div class="form-group"><label >{{ field.label }}</label>{{ field }}<span class="error-msg" style="color:red">{{ field.errors.0 }}</span></div>{% endfor %}</div></form></div><div class="modal-footer"><button type="button" class="btn btn-default" data-dismiss="modal">取 消</button><button id="btnSave" type="button" class="btn btn-primary">保 存</button></div></div></div></div><div class="container" style="margin-top: 15px" ><div class="panel panel-default"><div class="panel-heading"><span class="glyphicon glyphicon-list" aria-hidden="true"></span> 訂單列表</div><table class="table table-bordered"><thead><tr><th>ID</th><th>訂單</th><th>商品</th><th>價格</th><th>狀態</th><th>用戶</th><th>操作</th></tr></thead><tbody>{% for obj in queryset %}<tr><td>{{ obj.id }}</td><td>{{ obj.oid }}</td><td>{{ obj.title }}</td><td>{{ obj.price }}</td><td>{{ obj.get_status_display }}</td><td>{{ obj.admin.username }}</td><td><input uid="{{ obj.id }}" class="btn btn-primary btn-xs btn-edit" type="button" value="編輯"><input uid="{{ obj.id }}" class="btn btn-danger btn-xs btn-delete" type="button" value="刪除"></td></tr>{% endfor %}</tbody></table></div><nav aria-label="Page navigation"><ul class="pagination">{{ page_string }}</ul></nav></div><div class="modal fade" id="deleteModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel"><div class="modal-dialog" role="document"><div class="modal-content"><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" id="myModalLabel">刪除訂單</h4></div><div class="modal-body"><span style="color: red">確定要刪除嗎? 刪除之后數據將無法找回</span></div><div class="modal-footer"><button id="btnConfirmDelete" type="button" class="btn btn-primary">確 認</button><button type="button" class="btn btn-default" data-dismiss="modal">取 消</button></div></div></div></div>{% endblock %}{% block js %}<script type="text/javascript">var DELETE_ID;var EDIT_ID;$(function (){bindBtnAddEvent();bindBtnSaveEvent();bindBtnDeleteEvent();bindBtnConfirmDeleteEvent();bindBtnEditEvent();})function bindBtnAddEvent() {$("#btnAdd").click(function () {//在新建的時候保存前將編輯的id 設置為undefined;EDIT_ID = undefined;//清空表單, $("#formAdd")是jquery對象, $("#formAdd")[0]是DOM對象$("#formAdd")[0].reset()//修改標題為新建$("#myModalLabel").text('新建')//點擊新建按鈕,顯示對話框$('#myModal').modal('show');});}function bindBtnSaveEvent() {$("#btnSave").click(function (){//清除錯誤信息$(".error-msg").empty();if(EDIT_ID){//編輯doedit();}else {//新建doadd();}});}function doadd(){//向后臺發送請求$.ajax({url: "/order/add/",type: "post",data: $("#formAdd").serialize(),dataType: "JSON",success:function (res){if(res.status){//alert("創建成功")//清空表單, $("#formAdd")是jquery對象, $("#formAdd")[0]是DOM對象$("#formAdd")[0].reset()//關閉對話框$('#myModal').modal('hide');//刷新頁面location.reload();} else {//把錯誤信息顯示在對話框中$.each(res.error, function (name,errorList) {$("#id_" + name).next().text(errorList[0]);})}}})}function doedit(){//向后臺發送請求$.ajax({url: "/order/edit/?uid=" + EDIT_ID,type: "post",data: $("#formAdd").serialize(),dataType: "JSON",success:function (res){if(res.status){//alert("創建成功")//清空表單, $("#formAdd")是jquery對象, $("#formAdd")[0]是DOM對象$("#formAdd")[0].reset()//關閉對話框$('#myModal').modal('hide');//刷新頁面location.reload();} else {if(res.msg){alert(res.msg)}else {//把錯誤信息顯示在對話框中$.each(res.error, function (name,errorList) {$("#id_" + name).next().text(errorList[0]);})}}}})}function bindBtnDeleteEvent(){$(".btn-delete").click(function () {$("#deleteModal").modal('show');//獲取當前行的id ,并賦值給全局變量DELETE_ID = $(this).attr('uid');});}function bindBtnConfirmDeleteEvent(){$("#btnConfirmDelete").click(function (){//點擊確認按鈕后,將要刪除的id,發送到后臺$.ajax({url: "/order/delete",type: "GET",dataType: "JSON",data: {uid: DELETE_ID},success:function (res){if(res.status){location.reload();} else {alert(res.error);}}})});}function bindBtnEditEvent(){$(".btn-edit").click(function (){//向后臺發送ajax請求,獲取當前行的信息var uid = $(this).attr('uid');EDIT_ID = uid;$.ajax({url: "/order/detail/",type: "GET",data: {uid: uid},dataType: "JSON",success: function (res){if(res.status){//清空表單, $("#formAdd")是jquery對象, $("#formAdd")[0]是DOM對象$("#formAdd")[0].reset()//修改標題為編輯$("#myModalLabel").text('編輯')//點擊編輯按鈕,顯示對話框$('#myModal').modal('show');$.each(res.data, function (name,value){$("#id_" + name).val(value)})}else {alert(res.error);}}})});}</script>
{% endblock %}
頁面效果如下: