【Django】教程-11-ajax弹窗实现增删改查
【Django】教程-1-安装+创建项目+目录结构介绍
【Django】教程-2-前端-目录结构介绍
【Django】教程-3-数据库相关介绍
【Django】教程-4-一个增删改查的Demo
【Django】教程-5-ModelForm增删改查+规则校验【正则+钩子函数】
【Django】教程-6-搜索框-条件查询前后端
【Django】教程-7-分页,默认使用django的
【Django】教程-8-页面时间组件
【Django】教程-9-登录+退出
【Django】教程-10-ajax请求Demo,结合使用
17. ajax弹窗方式实现-增删改查
由下面几个模块组成 : model -> From -> urls -> views ->html
17.1 model
models.py
from django.utils import timezone
from django.db import modelsclass Order(models.Model):""" 订单表"""num = models.CharField(verbose_name="订单号", max_length=64)goods_name = models.CharField(verbose_name="商品名称", max_length=64)price = models.IntegerField(verbose_name="价格")status_choices = ((1, "待支付"),(2, "已支付"),)status = models.SmallIntegerField(verbose_name="订单状态", choices=status_choices, default=1)seller = models.ForeignKey(verbose_name="客服", to="UserInfo", on_delete=models.CASCADE)class UserInfo(models.Model):'''用户表'''name = models.CharField(verbose_name="姓名", max_length=32)password = models.CharField(verbose_name="密码", max_length=64)age = models.IntegerField(verbose_name="年龄")# create_time = models.DateTimeField(verbose_name="创建时间", default=timezone.now)create_time = models.DateField(verbose_name="创建时间", default=timezone.now)depart = models.ForeignKey(verbose_name="部门", to="Department", to_field="id", null=True, blank=True,on_delete=models.SET_NULL)gender_choices = ((1, "男"),(2, "女"),)gender = models.SmallIntegerField(verbose_name="性别", choices=gender_choices, default=1)# 数据状态status_choices = ((1, "已删除"),(0, "可用"),)status = models.SmallIntegerField(verbose_name="数据状态", choices=status_choices, default=0)def __str__(self):return self.name
17.2 Form
forms.py
from django import forms
from django.core.exceptions import ValidationError
from django.core.validators import RegexValidatorfrom . import models
from .models import Department, UserInfo, Admin, Order
from .util.md5 import md5class BootstrapModelForm(forms.ModelForm):def __init__(self, *args, **kwargs):super().__init__(*args, **kwargs)# 循环Modelform中所有字段,给每个字段插件设置for name, field in self.fields.items():if field.widget.attrs:field.widget.attrs["class"] = "form-control"field.widget.attrs["placeholder"] = field.labelelse:field.widget.attrs = {"class": "form-control", "placeholder": field.label}def as_div(self):"""自定义表单渲染方法,将错误信息显示在字段下方并设置为红色"""output = []for bound_field in self:label_html = f'<label for="{bound_field.id_for_label}">{bound_field.label}</label>'field_html = f'<div class="form-group">{label_html}{bound_field}</div>'if bound_field.errors:error_html = ''.join([f'<span class="text-danger">{error}</span>' for error in bound_field.errors])field_html += f'<div class="error-message">{error_html}</div>'output.append(field_html)return '\n'.join(output)class OrderForm(BootstrapModelForm):class Meta:model = Order# fields = "__all__"exclude = ["num", "id"]
17.3 urls
urls.py
from django.contrib import admin
from django.urls import path
from appTang.views import department_views, user_views, admin_views, account, order_view# 映射关系,视图--->函数
urlpatterns = [
# --------------------订单管理------------path('order/list', order_view.list),path('order/add', order_view.add),path('order/del', order_view.delete),path('order/detail', order_view.detail),path('order/edit', order_view.edit),]
17.4 views
views.py
import random
from datetime import datetimefrom django.core.paginator import Paginator
from django.http import JsonResponse
from django.shortcuts import redirect, render
from django.views.decorators.csrf import csrf_exemptfrom appTang.forms import OrderForm
from appTang.models import Orderdef list(request):"""用户展示"""# 搜索条件data_dict = {}query_name = request.GET.get("query_name", "") # 第二个值是默认值, 也可以写if判断if query_name:data_dict["name__contains"] = query_nameorder_list = Order.objects.filter(**data_dict).order_by("-id")paginator = Paginator(order_list, 5)# 获取当前页码,默认为第 1 页page_number = request.GET.get('page')page_obj = paginator.get_page(page_number)context = OrderForm()return render(request, 'order/order_list.html', {'page_obj': page_obj, 'context': context})@csrf_exempt
def add(request):form = OrderForm(data=request.POST)if form.is_valid():form.instance.num = datetime.now().strftime('%Y%m%d%H%M%S') + str(random.randint(1000, 9999))form.save()return JsonResponse({"status": True})return JsonResponse({"status": False, "error": form.errors})def delete(request):"""删除订单"""uid = request.GET.get("uid")exists = Order.objects.filter(id=uid).exists()if not exists:return JsonResponse({"status": False, "error": "数据不存在,删除失败!"})Order.objects.filter(id=uid).delete()return JsonResponse({"status": True})def detail(request):"""编辑订单,回显"""uid = request.GET.get("uid")row_dict = Order.objects.filter(id=uid).values("goods_name", "status", "price", "seller").first()if not row_dict:return JsonResponse({"status": False, "error": "数据不存在,编辑失败!"})return JsonResponse({"status": True, "data": row_dict})@csrf_exempt
def edit(request):"""编辑订单"""uid = request.GET.get("uid")row_obj = Order.objects.filter(id=uid).first()if not row_obj:return JsonResponse({"status": False, "tips": "数据不存在!请刷新重试!"})form = OrderForm(data=request.POST, instance=row_obj)if form.is_valid():form.save()return JsonResponse({"status": True})return JsonResponse({"status": False, "error": form.errors})
17.5 html
order_list.html
{% extends 'login/layout.html' %}
{% load static %}{% block content %}<div class="container"><div style="margin-bottom: 10px"><input id="btnAdd" type="button" value="新建订单js" class="btn btn-success"><input type="button" value="新建订单2-css" class="btn btn-success" data-toggle="modal" data-target="#myModal"></div><div class="panel panel-default"><div class="panel-heading"><span class="glyphicon glyphicon-th-list" aria-hidden="true"></span>订单列表</div><table class="table table-bordered"><thead><tr><th>#</th><th>订单号</th><th>商品名称</th><th>价格</th><th>状态</th><th>客服</th><th>操作</th></tr></thead><tbody>{% for i in page_obj %}<tr><td>{{ i.id }}</td><td>{{ i.num }}</td><td>{{ i.goods_name }}</td><td>{{ i.price }}</td><td>{{ i.get_status_display }}</td><td>{{ i.seller }}</td><td><input uid="{{ i.id }}" class="btn btn-primary btn-xs btn-edit" type="button" value="编辑"><input uid="{{ i.id }}" class="btn btn-danger btn-xs btn-delete" type="button" value="删除"></td></tr>{% endfor %}</tbody></table></div><!-- 分页导航 --><nav aria-label="分页"><ul class="pagination justify-content-center"style="display: flex; flex-wrap: nowrap; align-items: center;"><!-- 首页 -->{% if page_obj.has_previous %}<li class="page-item"><a class="page-link" href="?page=1">首页</a></li>{% else %}<li class="page-item disabled"><span class="page-link">首页</span></li>{% endif %}<!-- 上一页 -->{% if page_obj.has_previous %}<li class="page-item"><a class="page-link" href="?page={{ page_obj.previous_page_number }}">上一页</a></li>{% else %}<li class="page-item disabled"><span class="page-link">上一页</span></li>{% endif %}<!-- 下拉选择页码 --><li class="page-item" style="margin: 0 5px;"><select class="form-control" onchange="goToPage(this.value)">{% for page_num in page_obj.paginator.page_range %}<option value="{{ page_num }}" {% if page_num == page_obj.number %}selected{% endif %}>第 {{ page_num }} 页</option>{% endfor %}</select></li><!-- 显示当前页码和总页数 --><li class="page-item disabled" aria-current="page" style="margin: 0 5px;"><span class="page-link">共 {{ page_obj.paginator.num_pages }} 页</span></li><!-- 下一页 -->{% if page_obj.has_next %}<li class="page-item"><a class="page-link" href="?page={{ page_obj.next_page_number }}">下一页</a></li>{% else %}<li class="page-item disabled"><span class="page-link">下一页</span></li>{% endif %}<!-- 尾页 -->{% if page_obj.has_next %}<li class="page-item"><a class="page-link" href="?page={{ page_obj.paginator.num_pages }}">尾页</a></li>{% else %}<li class="page-item disabled"><span class="page-link">尾页</span></li>{% endif %}</ul></nav></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"><spanaria-hidden="true">×</span></button><h4 class="modal-title" id="myModalLabel">新建订单</h4></div><div class="modal-body"><form id="formAdd"><div class="clearfix">{% for i in context %}<div class="col-xs-6"><div class="form-group" style=""><label>{{ i.label }}</label>{{ i }}<span class="error-msg" style="color: red"></span></div></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="modal fade" id="delModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel"><div class="modal-dialog" role="document"><div class="alert alert-danger alert-dismissible fade in" role="alert"><button type="button" class="close" data-dismiss="alert" aria-label="Close"><spanaria-hidden="true">×</span></button><h4>是否确认删除?</h4><p style="margin: 10px 10px;">删除后,所有关联都会被删除</p><p style="text-align: right"><button type="button" class="btn btn-danger" id="btnConfirmDel">确定</button><button type="button" class="btn btn-default" data-dismiss="modal">取消</button></p></div></div></div>{% endblock %}
{% block js %}<script src=https://code.jquery.com/jquery-3.6.0.min.js></script><script type="text/javascript">//声明 一个全部变量 delete_idvar DELETE_ID;var EDIT_ID;$(function () {bindBtnAddEvent();bindBtnSaveEvent();bindBtnDelEvent();bindBtnConfirmDelEvent();bindBtnEditEvent();})function bindBtnEditEvent() {$(".btn-edit").click(function () {// 清空对话框中的数据$("#formAdd")[0].reset()var uid = $(this).attr("uid")EDIT_ID = uid// 从后端获取数据,并回显展示$.ajax({url: "/order/detail",type: "GET",data: {uid: uid},dataType: "JSON",success: function (res) {// console.log(res)if (res.status) {// 讲数据,进行赋值$.each(res.data, function (name, value) {// console.log(name,value)$("#id_" + name).val(value);})// 设置编辑页$("#myModalLabel").text("编辑")// 点击编辑$("#myModal").modal('show');} else {alert(res.error)}}})})}function bindBtnConfirmDelEvent() {$("#btnConfirmDel").click(function () {// console.log("点击了确定按钮")// 点击确认删除按钮,将全局变量中设置的那个ID,发送到后台$.ajax({url: "/order/del",type: "GET",data: {uid: DELETE_ID},dataType: "JSON",success: function (res) {if (res.status) {// 隐藏弹窗// $("#delModal").modal('hide');// 页面刷新location.reload();} else {// 删除失败alert(res.error)}}})})}function bindBtnAddEvent() {$("#btnAdd").click(function () {// 将正在编辑的EDIT_ID置为空EDIT_ID = undefined;// 清空对话框中的数据$("#formAdd")[0].reset()$("#myModalLabel").text("新建")// 点击按钮显示对话框$("#myModal").modal('show');})}function bindBtnDelEvent() {$(".btn-delete").click(function () {// alert("点击了删除")// 弹出一个对话框$("#delModal").modal('show');// 获取当前uid 赋值 给全局变量// var uid = $(this).attr("uid")// console.log(uid)DELETE_ID = $(this).attr("uid")})}function bindBtnSaveEvent() {$("#btnSave").click(function () {// 清除错误信息$(".error-msg").empty()if (EDIT_ID) {// 编辑edit();} else {// 添加add();}})}function edit() {// 向后台发送请求$.ajax({url: "/order/edit" + "?uid=" + EDIT_ID, // /order/edit?uid=3type: "POST",data: $("#formAdd").serialize(),dataType: "JSON",success: function (res) {if (res.status) {alert("编辑保存成功!")// 清空表单,$("#formAdd")jQuery对象->Dom对象$("#formAdd")[0]$("#formAdd")[0].reset();// 关闭对话框$("#myModal").modal('hide');// 页面刷新location.reload()} else {if (res.tips) {alert(res.tips)} else {$.each(res.error, function (name, errorList) {$("#id_" + name).next().text(errorList[0]);})}}}})}function add() {// 向后台发送请求$.ajax({url: "/order/add",type: "POST",data: $("#formAdd").serialize(),dataType: "JSON",success: function (res) {if (res.status) {alert("创建成功!")// 清空表单,$("#formAdd")jQuery对象->Dom对象$("#formAdd")[0]$("#formAdd")[0].reset();// 关闭对话框$("#myModal").modal('hide');// 页面刷新location.reload()} else {$.each(res.error, function (name, errorList) {$("#id_" + name).next().text(errorList[0]);})}}})}</script>
{% endblock %}
17.6 目录结构

相关文章:
【Django】教程-11-ajax弹窗实现增删改查
【Django】教程-1-安装创建项目目录结构介绍 【Django】教程-2-前端-目录结构介绍 【Django】教程-3-数据库相关介绍 【Django】教程-4-一个增删改查的Demo 【Django】教程-5-ModelForm增删改查规则校验【正则钩子函数】 【Django】教程-6-搜索框-条件查询前后端 【Django】教程…...
结构化需求分析:专业方法论与实践
结构化需求分析是一种用于软件开发或其他项目中的系统分析方法,旨在全面、准确地理解和描述用户对系统的需求。以下是关于结构化需求分析的详细介绍: 一、概念 结构化需求分析是采用自顶向下、逐步分解的方式,将复杂的系统需求分解为若干个…...
R语言:气象水文领域的数据分析与绘图利器
R 语言是一门由统计学家开发的用于统计计算和作图的语言(a Statistic Language developed for Statistic by Statistician),由 S 语言发展而来,以统计分析功能见长。R 软件是一款集成 了数据操作、统计和可视化功能的优秀的开源软…...
Kotlin与HttpClient编写视频爬虫
想用Apache HttpClient库和Kotlin语言写一个视频爬虫。首先,我需要确定用户的具体需求。视频爬虫通常涉及发送HTTP请求,解析网页内容,提取视频链接,然后下载视频。可能需要处理不同的网站结构,甚至可能需要处理动态加载…...
图形化编程语言:低代码赛道的技术革命与范式突破
在 2024 年 Gartner 低代码平台魔力象限报告中,传统低代码厂商市场份额增速放缓至 12%,而图形化编程语言赛道融资额同比激增 370%。本文深度剖析低代码平台的技术瓶颈,系统阐释图形化编程语言的核心优势,揭示其如何重构软件开发范…...
蓝桥杯每日刷题c++
目录 P9240 [蓝桥杯 2023 省 B] 冶炼金属 - 洛谷 (luogu.com.cn) P8748 [蓝桥杯 2021 省 B] 时间显示 - 洛谷 (luogu.com.cn) P10900 [蓝桥杯 2024 省 C] 数字诗意 - 洛谷 (luogu.com.cn) P10424 [蓝桥杯 2024 省 B] 好数 - 洛谷 (luogu.com.cn) P8754 [蓝桥杯 2021 省 AB2…...
快速上手示例(以BEVFormer为例)
快速上手示例(以BEVFormer为例) 安装依赖: bash git clone https://github.com/fundamentalvision/BEVFormer.git cd BEVFormer pip install -r requirements.txt下载预训练模型: wget https://github.com/fundament…...
GitHub 上开源一个小项目的完整指南
GitHub 上开源一个小项目的完整指南 🚀 第一步:准备你的项目 在开源之前,确保项目是可用且有一定结构的: ✅ 最低要求 项目文件清晰、结构合理(比如:src/、README.md、LICENSE)项目能在本地正…...
当实体类中的属性名和表中的字段名不一样 ,怎么办
在不同的持久化框架中,当实体类中的属性名和表中的字段名不一致时,有不同的解决办法,下面为你详细介绍: 1. MyBatis MyBatis 是一个流行的持久层框架,有两种主要方式来处理属性名和字段名不一致的情况。 方式一&…...
arthas之dump/classloader命令的使用
文章目录 1. dump2. classloader 1. dump 作用:将已加载类的字节码文件保存到特定目录:logs/arthas/classdump/ 参数 数名称参数说明class-pattern类名表达式匹配[c:]类所属 ClassLoader 的 hashcode[E]开启正则表达式匹配,默认为通配符匹…...
linux 使用 usermod 授权 普通用户 属组权限
之前写过这篇文章 linux 普通用户 使用 docker 只不过是使用 root 用户编辑 /etc/group用户所属组文件的方式 今天带来一种 usermod 命令行方式 以下3步,在root用户下操作 第一步,先创建一个普通用户测试使用 useradd miniuser第二步,授权到…...
大文件上传之断点续传实现方案与原理详解
一、实现原理 文件分块:将大文件切割为固定大小的块(如5MB) 进度记录:持久化存储已上传分块信息 续传能力:上传中断后根据记录继续上传未完成块 块校验机制:通过哈希值验证块完整性 合并策略:所…...
第一次3D打印,一个简单的小方块(Rhino)
一、建模 打开犀牛,我们选择立方体 我们点击上册的中心点 输入0,然后回车0 而后我们输长度:10,回车确认 同样的,宽度10 高度同样是10 回车确认后,我们得到一个正方形 二、导出模型 我们选择文件—>保存…...
java基础使用- 泛型
泛型 泛型作用泛型语法(1) 泛型类/接口(2) 泛型方法 类型参数命名习惯类型通配符(Wildcards)(1) 无界通配符 <?>表示“未知类型”(2) 上界通配符 <? extends T>表示“T 或 T 的子类”。(3) 下界通配符 <? super T>表示“T 或 T 的父…...
VMware-workstation-full-12.5.2 install OS X 10.11.1(15B42).cdr
手把手虚拟机安装苹果操作系统 VMware_workstation_full_12.5.2 unlocker208 Apple Max OS X(M)-CSDN博客 vcpu-0:VERIFY vmcore/vmm/main/physMem_monitor.c:1180 FILE: FileCreateDirectoryRetry: Non-retriable error encountered (C:\ProgramData\VMware): Cann…...
5分钟上手GitHub Copilot:AI编程助手实战指南
引言 近年来,AI编程工具逐渐成为开发者提升效率的利器。GitHub Copilot作为由GitHub和OpenAI联合推出的智能代码补全工具,能够根据上下文自动生成代码片段。本文将手把手教你如何快速安装、配置Copilot,并通过实际案例展示其强大功能。 一、…...
deepseek使用记录26——从体力异化到脑力异化
我们的一切发现和进步,似乎结果是使物质力量具有理智生命,而人的生命则化为愚钝的物质力量。AI快速发展的现实中,人面临着比工业革命更深刻的异化。在工业革命中,人的身躯沦为了机器的一部分,而现在人的脑袋沦为了AI的…...
数字身份DID协议:如何用Solidity编写去中心化身份合约
本文提出基于以太坊的自主主权身份(SSI)实现方案,通过扩展ERC-734/ERC-735标准构建链上身份核心合约,支持可验证声明、多密钥轮换、属性隐私保护等特性。设计的三层架构体系将身份控制逻辑与数据存储分离,在测试网环境…...
【Git “ls-tree“ 命令详解】
本章目录: 1. 命令简介2. 命令的基本语法和用法基本语法常见使用场景示例 1:查看当前提交的文件树示例 2:查看某个分支的文件树示例 3:查看特定路径下的文件树 3. 命令的常用选项及参数常用选项: 4. 命令的执行示例示例 1…...
[ctfshow web入门] web16
信息收集 提示:对于测试用的探针,使用完毕后要及时删除,可能会造成信息泄露 试试url/phpinfo.php url/phpsysinfo.php url/tz.php tz.php能用 点击phpinfo,查看phpinfo信息,搜索flag,发现flag被保存为变量…...
全面支持MCP协议,开启便捷连接之旅,MaxKB知识库问答系统v1.10.3 LTS版本发布
2025年4月7日,MaxKB开源知识库问答系统正式发布v1.10.3 LTS版本。 在MaxKB v1.10.3 LTS版本中,应用方面,MaxKB新增支持MCP调用节点,AI对话节点新增MCP工具调用功能,支持设置MCP服务配置;函数库方面&#x…...
ES:geoip_databases
目录 如何查看 .geoip_databases 的内容1. 查看 .geoip_databases 的内容2. 查看GeoIP数据库的统计信息3. 使用GeoIP处理器4. 管理GeoIP数据库更新 如何查看 .geoip_databases 的内容 在Elasticsearch中,.geoip_databases 是一个特殊的索引,用于存储Geo…...
VTK知识学习(51)- 交互与Widget(二)
1、交互器样式 前面所讲的观察者/命令模式是 VTK实现交互的方式之一。在前面示例 所示的窗口中可以使用鼠标与柱体进行交互,比如用鼠标滚轮可以对柱体放大、缩小;按下鼠标左键不放,然后移动鼠标,可以转动柱体;按下鼠标左键,同时按…...
底盘---麦克纳姆轮(Mecanum Wheel)
一、基本定义与起源 定义:麦克纳姆轮是一种实现全向移动的特殊轮式结构,通过在主轮周边安装多个倾斜的辊子(小轮),使设备能够在平面上向任意方向移动(包括横向、斜向、旋转等),无需…...
深入源码级别看spring bean创建过程
我们通常聊到spring bean的生命周期,大多是从网上找帖子背些基本概念,这样我们学到的东西是不够直观清晰的,这篇文章我就试着从源码级别来讲清楚bean的创建过程。 一、准备demo代码 我们既然要深入源码来看bean的创建过程,那么就…...
I/O进程1
day1 一、标准IO 1.概念 在C库中定义的一组用于输入输出的函数 2.特点 (1).通过缓冲机制减少系统调用,提高效率 (2.)围绕流进行操作,流用FILE *来描述(3).标准IO默认打开了三个流,stdin(标准输入)、stdout(…...
int 与 Integer 的区别详解
1. 本质区别 特性intInteger类型基本数据类型(Primitive)包装类(Wrapper Class)存储位置栈(或作为对象成员在堆中)堆(对象实例)默认值0null(可能导致 NullPointerExcept…...
Java面试黄金宝典39
1. SNMP、SMTP 协议 SNMP(简单网络管理协议) 定义:SNMP 是一种应用层协议,用于在 IP 网络中管理网络节点(如服务器、路由器、交换机等)。它允许网络管理员监控网络设备的状态、收集性能数据、进行故障诊断等操作。SNMP 基于 UDP 协议,采用轮询和事件驱动相结合的方式来收…...
解决Python与Anaconda中pip的冲突,安装包失败问题(此应用无法在你电脑上运行,无法访问)
1、Anaconda安装在D盘 2、Python安装在C盘(当时刚换电脑,新电脑还未分盘,着急用python直接安装) 问题: (1)winr,cmd无法访问c盘下的pip,安装包失败。采用管理者身份&…...
Java全栈面试宝典:JMM内存模型与Spring自动装配深度解析
目录 一、Java内存模型(JMM)核心原理 🔥 问题8:happens-before原则全景解析 JMM内存架构图 happens-before八大规则 线程安全验证案例 🔥 问题9:JMM解决可见性的三大武器 可见性保障机制 volatile双…...
