当先锋百科网

首页 1 2 3 4 5 6 7

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 JsonResponse

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

3、示例,使用ajax 实现订单功能的增删改查

1、 定义订单表,在models.py中,定义表结构

from django.db import models

class Admin(models.Model):
    username = models.CharField(verbose_name="用户名",max_length=16)
    passwd = models.CharField(verbose_name="密码",max_length=64)

    def __str__(self):
        return self.username

class 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,order

urlpatterns = [
    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 Pagination

class 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 = True
        self.query_dict = query_dict

        page = request.GET.get(page_param,"1")
        if page.isdecimal():
            page = int(page)
        else:
            page = 1

        self.page = page
        self.page_size = page_size
        self.start = (page-1)* page_size
        self.end = page * page_size

        self.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 += 1
        self.total_page_count = total_page_count
        self.plus = plus
        self.page_param = page_param

    def html(self):
        #计算出,显示当前页的前5页,后5页
        if self.total_page_count <= 2 * self.plus + 1:
            #数据库中的数据比较少,没有11页
            start_page = 1
            end_page = self.total_page_count
        else:
            # 数据库中的数据比较多,大于11页
            # 当前页<5时,(小级值)
            if self.page <= self.plus:
                start_page = 1
                end_page = 2 * self.plus + 1
            else:
                # 当前页大于5
                #当前页 + 5 > 总页面
                if (self.page + self.plus) > self.total_page_count:
                    start_page = self.total_page_count - 2*self.plus
                    end_page = self.total_page_count
                else:
                    start_page = self.page - self.plus
                    end_page = self.page + self.plus
        # 页码
        page_str_list = []
        self.query_dict.setlist(self.page_param,[1])
        page_str_list.append('<li><a href="?{}" target="_blank" rel="external nofollow"  target="_blank" rel="external nofollow"  target="_blank" rel="external nofollow"  target="_blank" rel="external nofollow"  target="_blank" rel="external nofollow"  target="_blank" rel="external nofollow"  target="_blank" rel="external nofollow"  target="_blank" rel="external nofollow" >首页</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="?{}" target="_blank" rel="external nofollow"  target="_blank" rel="external nofollow"  target="_blank" rel="external nofollow"  target="_blank" rel="external nofollow"  target="_blank" rel="external nofollow"  target="_blank" rel="external nofollow"  target="_blank" rel="external nofollow"  target="_blank" rel="external nofollow" >上一页</a></li>'.format(self.query_dict.urlencode())
        else:
            self.query_dict.setlist(self.page_param, [1])
            prev = '<li><a href="?{}" target="_blank" rel="external nofollow"  target="_blank" rel="external nofollow"  target="_blank" rel="external nofollow"  target="_blank" rel="external nofollow"  target="_blank" rel="external nofollow"  target="_blank" rel="external nofollow"  target="_blank" rel="external nofollow"  target="_blank" rel="external nofollow" >上一页</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="?{}" target="_blank" rel="external nofollow"  target="_blank" rel="external nofollow"  target="_blank" rel="external nofollow"  target="_blank" rel="external nofollow"  target="_blank" rel="external nofollow"  target="_blank" rel="external nofollow"  target="_blank" rel="external nofollow"  target="_blank" rel="external nofollow" >{}</a></li>'.format(self.query_dict.urlencode(),i)
            else:
                self.query_dict.setlist(self.page_param, [i])
                ele = '<li><a href="?{}" target="_blank" rel="external nofollow"  target="_blank" rel="external nofollow"  target="_blank" rel="external nofollow"  target="_blank" rel="external nofollow"  target="_blank" rel="external nofollow"  target="_blank" rel="external nofollow"  target="_blank" rel="external nofollow"  target="_blank" rel="external nofollow" >{}</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="?{}" target="_blank" rel="external nofollow"  target="_blank" rel="external nofollow"  target="_blank" rel="external nofollow"  target="_blank" rel="external nofollow"  target="_blank" rel="external nofollow"  target="_blank" rel="external nofollow"  target="_blank" rel="external nofollow"  target="_blank" rel="external nofollow" >下一页</a></li>'.format(self.query_dict.urlencode())
        else:
            self.query_dict.setlist(self.page_param, [self.total_page_count])
            prev = '<li><a href="?{}" target="_blank" rel="external nofollow"  target="_blank" rel="external nofollow"  target="_blank" rel="external nofollow"  target="_blank" rel="external nofollow"  target="_blank" rel="external nofollow"  target="_blank" rel="external nofollow"  target="_blank" rel="external nofollow"  target="_blank" rel="external nofollow" >下一页</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="?{}" target="_blank" rel="external nofollow"  target="_blank" rel="external nofollow"  target="_blank" rel="external nofollow"  target="_blank" rel="external nofollow"  target="_blank" rel="external nofollow"  target="_blank" rel="external nofollow"  target="_blank" rel="external nofollow"  target="_blank" rel="external nofollow" >尾页</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():
        #保存数据之前生成oid
        form.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">&times;</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">&times;</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 %}

页面效果如下:
在这里插入图片描述