django中使用ajax发送请求

1、ajax简单介绍

浏览器向网站发送请求时 是以URL和表单的形式提交的post 或get 请求,特点是:页面刷新

除此之外,也可以基于ajax向后台发送请求(异步)

依赖jQuery

编写ajax代码

javascript 复制代码
$.ajax(
    {
        url: "发送的地址" ,
        type: "post",
        data:{
            n1:123,
            n2:456        
        },
        success:function(res){
                    
        }   
    }
)

2、在django 使用中了解的知识点

1、在django 中使用ajax发送post请求,通过下面方法免除csrf_token

python 复制代码
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、想要去数据库中获取数据时:可以是对象也可以是字典

python 复制代码
# 对象,当前行的所有数据
row_object = models.Order.objects.filter(id=uid).first()
row_object.id
row_object.title

也可以直接获取字典

python 复制代码
# 字典,{"id":1,"title":"xxx"}
row_dict = models.Order.objects.filter(id=uid).values("id","title").filter()
python 复制代码
# 列表 [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序列化,简化代码

python 复制代码
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中,定义表结构

python 复制代码
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中写接口路径

python 复制代码
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中实现不同功能的函数

  • 列表展示 (查询)
python 复制代码
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)

这里使用到了分页的方法,分页方法如下:

python 复制代码
"""
自定义的分页组件,以后如果想要使用这个分页组件,你需要做的如下几件事:

在视图函数 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="?{}">首页</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
  • 订单的创建
python 复制代码
@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})
  • 订单的删除
python 复制代码
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 查询订单信息
python 复制代码
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)
  • 编辑订单
python 复制代码
@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

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

页面效果如下:

相关推荐
Mr数据杨20 分钟前
【Codex】用部门管理模块维护组织架构与管理层级
架构·django·codex·项目开发
Mr数据杨21 分钟前
【Codex】用附件管理模块统一维护系统文件资源
django·codex·项目开发
IT毕设实战小研1 小时前
基于安卓的空气质量查询系统
android·大数据·vue.js·爬虫·python·django·课程设计
Mr数据杨5 小时前
【Codex】用座位划分模块优化班级空间与课堂管理
django·codex·项目开发
Mr数据杨5 小时前
【Codex】用系统配置工作台集中维护平台运行参数
django·codex·项目开发
Mr数据杨8 小时前
【Codex】用学生生活日常模块记录校园生活过程
django·生活·codex·项目开发
Mr数据杨8 小时前
【Codex】用角色管理模块控制不同岗位的数据与操作权限
django·codex·项目开发
Mr数据杨9 小时前
【Codex】用用户管理模块维护后台账号与登录权限
django·codex·项目开发
Mr数据杨11 小时前
【Codex】用学生支持周报模块跟踪个性化支持进展
android·java·javascript·django·codex·项目开发