django学习
目录项目源码相关文章基本默认项目app模板语法DTL变量标签请求与响应基础结构HttpRequest 对象HttpResponse 对象数据库操作MySQL数据库 pymysqlORM模板的继承Form和ModelForm组件Form 组件ModelForm 组件其他关于一些校验关于数据库搜索关于分页django的中间件AJAX请求图表文件上传Excel上传项目源码本项目的完整代码已上传至 GitHub欢迎 Star 和 Fork [GitHub 项目地址](https://github.com/Zhan-CF/django-user-manage.git)如果对您有帮助请给个 ⭐️ Star 支持一下相关文章HTMLCSSJShttps://blog.csdn.net/weixin_64555419/article/details/159431406?spm1011.2415.3001.10575sharefrommp_manage_link基本django在终端创建目录的命令cd django项目目录要将项目创建在哪里 #我统一放在D:\pycharmfile\djangoProject django-admin startproject 项目名称默认项目django_test2 manage.py //项目的管理启动项目创建app数据管理不动 django_test2 __init__.py setting.py //项目配置动 urls.py //URL路径和函数的对应关系动 asgi.py //接收网络请求不动 wsgi.py //接收网络请求不动app一个项目下可以有多个app相互独立负责不同的模块不过一般只创一个app。创建app切换到主目录下在pycharm终端输入命令D:\pycharmfile\mydjangoProject\django_test2 python manage.py startapp app0创建的app下的初始项目app0 migrations //固定不动数据库变更记录 __init__.py __init__.py admin.py //固定不动django默认提供了admin后台管理功能一般不用 apps.py //固定不动app启动类 models.py //动对数据库操作 tests.py //固定不动单元测试一般不用 views.py //动函数一般定义在这注册app在seetings.py文件里的INSTALLED_APPS那里添加一行app0.apps.App0Config其中app0是创建的app的名字。编写URL与函数的关系在views.py里编写函数在urls.py里创建关系.编写一个基本函数def index(request): #request是默认参数 #request是一个对象封装了用户通过浏览器发送过来的所有数据 return HttpResponse(欢迎) #返回一个字符串 def user_add(request): return render(request,user_add.html) #返回一个html页面 #在创建的app目录下创建templates目录在里面创建html文件启动django项目pycharm命令行启动Python manage.py runserverpycharm点运行按钮启动静态资源加载包括图片、CSS、JS等先在app目录下创建static目录将资源放到里面。在html中加载此资源时先在文件开头写{% load static %}若是加载CSS在head标签末尾写link relstylesheet href{% static plugins/bootstrap-3.4.1/css/bootstrap.css %}若是加载图片在插入地方写img src{% static img/1.png %} alt若是引入JS在body末尾写script src{% static js/jquery-3.6.0.min.js}/script script src{% static plugins/bootstrap-3.4.1/js/bootstrap.js}/script模板语法DTLDTL 的语法分为四大核心块变量、标签、过滤器、继承。模板语法写在templates的html文件里在views函数的render内部会先读取含有模板语法的html文件然后内部进行渲染模板语法执行并替换数据最后将渲染完成后只包含html标签的字符串返还给用户浏览器。变量使用双大括号来显示从 Python 视图函数views.py传过来的数据。基本显示{{ username }}字典取值{{ player.hp }}(对应 Python 的player[hp])对象属性/方法{{ user.get_full_name }}(调用方法不需要加括号)列表索引{{ skills.0 }}(对应 Python 的skills[0])标签标签负责逻辑判断和循环使用百分号包裹。A. 循环标签 (for)常用于遍历数据库查询到的列表如通关副本列表。ul {% for task in task_list %} li第{{ forloop.counter }}项{{ task.name }}/li {% empty %} li当前暂无副本任务/li {% endfor %} /ul提示forloop.counter是内置计数器从 1 开始。B. 条件判断 (if){% if user_level 10 %} p classtext-danger称号高级玩家/p {% elif user_level 5 %} p classtext-warning称号进阶玩家/p {% else %} p称号菜鸟/p {% endif %}C. URL 解析 (url)不要硬编码链接使用路由别名a href{% url login_page %}点击登录/a请求与响应基础结构在 Django 的views.py中每个视图函数都必须接收一个request对象并且必须返回一个response对象。from django.shortcuts import render, HttpResponse def my_view(request): # 1. 收到请求 (request) # 2. 逻辑处理 (计算、查数据库) # 3. 返回响应 (response) return HttpResponse(天网系统已就绪)HttpRequest 对象当用户访问网页时Django 会自动创建一个HttpRequest对象。常用的属性如下属性/方法示例作用request.methodGET或POST判断请求类型非常重要。request.GETrequest.GET.get(id)获取 URL 路径里的参数如?id1。request.POSTrequest.POST.get(name)获取表单提交的数据如登录名。request.FILESrequest.FILES.get(avatar)获取上传的文件。request.path/welcome/获取当前的请求路径。request.is_ajax()(老版本) /headers判断是否为异步请求。HttpResponse 对象给用户回信Django 提供了几种常用的响应方式对应不同的业务场景A. 返回纯文本/HTML (HttpResponse)最基础的响应直接返回字符串。return HttpResponse(h1警告灵魂扫描中/h1)B. 渲染模板 (render) ——最常用将 Python 数据填入 HTML 模板并返回。context {name: 萧暮雨, id: 001} return render(request, index.html, context)C. 页面重定向 (redirect)让用户跳转到另一个页面。from django.shortcuts import redirect return redirect(/login/) # 或者写路由别名D. 返回 JSON 数据 (JsonResponse) ——前后端分离核心如果你在写 API 接口这个是必修课。from django.http import JsonResponse data {status: success, score: 100} return JsonResponse(data)注意CSRF 防护Django 默认非常安全。当你使用POST提交数据时必须在 HTML 的post标签里加上{% csrf_token %}如果没有这一行Django 会出于安全考虑拒绝请求并返回403 Forbidden错误。数据库操作MySQL数据库 pymysqlimport pymysql # 1.连接MySQL conn pymysql.connect(host127.0.0.1, port3306, userroot, passwdroot123, charsetutf8, dbunicom) cursor conn.cursor(cursorpymysql.cursors.DictCursor) # 2.发送指令 cursor.execute(insert into admin(username,password,mobile) values(wupeiqi,qwe123,15155555555)) conn.commit() # 3.关闭 cursor.close() conn.close()ORM在 Django 中操作数据库不需要写原生的 SQL 语句如SELECT * FROM ...而是使用一种叫ORM (Object-Relational Mapping)的技术。简单来说orm充当了一个翻译的功能可以把我们写的Python代码翻译成对应的数据库查询语句这样不学数据库语句也能进行数据库操作。先安装第三方模块pip install mysqlclient接着去mysql创建数据库再用django连接数据库在settings.py文件中进行配置和修改。DATABASES { default: { ENGINE: django.db.backends.mysql, NAME: gx_day15, # 数据库名字 USER: root, PASSWORD: root123, HOST: 127.0.0.1, # 本机 PORT: 3306, #端口 } }第一步定义模型 (models.py)在 Django 项目的models.py中定义你的数据结构。from django.db import models class Player(models.Model): # 字符串字段必须指定最大长度 name models.CharField(max_length32) # 整数序列 iq models.IntegerField(default10) # 自动记录创建时间 create_time models.DateTimeField(auto_now_addTrue) def __str__(self): return self.name第二步同步到数据库 (Migrations)定义好类后需要执行两行命令Django 会自动帮你创建数据库表生成脚本python manage.py makemigrations检查 models.py 的变化生成记录。执行同步python manage.py migrate真正去数据库里建表。第三步增删改查 (CRUD) —— 核心操作这些代码通常写在views.py视图函数中。A. 增 (Create)# 方式 1 Player.objects.create(name萧暮雨, iq15) # 方式 2 (实例化后保存) p Player(name楚离, iq20) p.save()B. 查 (Retrieve)Django 提供了极其强大的查询接口方法示例作用all()Player.objects.all()获取表中所有数据返回 QuerySet 列表。filter()Player.objects.filter(iq10)获取所有智力等于 10 的人。get()Player.objects.get(id1)获取唯一的一条数据。如果找不到或多于一条会报错。exclude()Player.objects.exclude(nameXX)排除掉某个人。order_by()Player.objects.all().order_by(-iq)按智力倒序排列加减号代表倒序。想要去数据库中获取数据时对象/字典# 对象当前行的所有数据。 row_object models.Order.objects.filter(iduid).first() row_object.id row_object.title# 字典{id:1,title:xx} row_dict models.Order.objects.filter(iduid).values(id,title).first()# queryset [obj,obj,obj,] queryset models.Order.objects.all()# queryset [ {id:1,title:xx},{id:2,title:xx}, ] queryset models.Order.objects.all().values(id,title)# queryset [ (1,xx),(2,xxx), ] queryset models.Order.objects.all().values_list(id,title)C. 改 (Update)# 方式 1先查再改 p Player.objects.get(id1) p.iq 99 p.save() # 方式 2批量修改 Player.objects.filter(name萧暮雨).update(iq100)D. 删 (Delete)# 删除单条 Player.objects.get(id2).delete() # 批量删除 Player.objects.filter(iq__lt5).delete() # 删除智力小于 5 的人模板的继承可以定义一个包含网站公共元素如导航栏、页脚、侧边栏的母版然后让其他页面只负责填充变动的部分这样可以避免重复的cv并且维护起来也更方便。创建母版在母版中需要使用{% block 块名 %} ... {% endblock %}标签来“挖坑”。这些坑位将由子页面来填满。{% load static %} !DOCTYPE html html langen head meta charsetUTF-8 titleTitle/title link relstylesheet href{% static plugin/bootstrap-3.4.1/css/bootstrap.min.css %} /head body nav classnavbar navbar-default !--这部分原本是个完整的导航条这里省略不写了-- div classcontainer {% block content %} {% endblock %} /div script src{% static js/jquery-4.0.0.min.js %}/script script src{% static plugin/bootstrap-3.4.1/js/bootstrap.min.js %}/script /body /html创建子页面在第一行使用{% extends 母版文件名 %}声明继承关系。然后使用{% block 块名 %}来填坑。{% extends layout.html %} {% block content %} h2部门管理/h2 {% endblock %}{{ block.super }}在子页面的 block 内使用可以不覆盖母版内容保留母版内容并追加。Form和ModelForm组件对应项目的user模块跟着做了原始的新建用户理了理思路虽然做完也有点没记住。原始方式是本质但一般不会采用太麻烦。- 用户提交数据没有校验。 - 错误页面上应该有错误提示。 - 页面上没一个字段都需要我们重新写一遍。 [OK] - 关联的数据手动去获取并展示循环展示在页面。 [OK]在 Django 开发中手动在 HTML 里写input和在views.py里用request.POST.get拿数据是非常低效且容易出错的。为此Django 提供了Form和ModelForm。Form 组件Form组件不直接绑定数据库模型它更像是一个独立的验证器。主要功能自动生成 HTML你定义字段它帮你生成input标签。数据校验检查输入是否合法比如邮箱格式、密码长度。错误提示如果校验失败自动把错误信息传回前端。代码示例# views.py from django import forms class MyForm(forms.Form): username forms.CharField(label用户名, min_length3) password forms.CharField(label密码, widgetforms.PasswordInput) def user_add(request): form MyForm() #实例化 return render(request, user_add.html,{form:form}) # user_add.html form methodpost {{ form.user }} {{ form.pwd }} {{ form.email }} /form form methodpost #也可以写个循环更简单 {% for field in form%} {{ field }} {% endfor %} !-- input typetext placeholder姓名 nameuser / -- /formModelForm 组件ModelForm是Form的升级版。它可以直接绑定一个数据库模型 (Model)不用像Form一样再写一遍那些字段。极速开发它会自动读取models.py里的字段类型比如CharField对应文本框DateTimeField对应时间控件。一键保存校验通过后直接执行form.save()就能把数据存入数据库连objects.create()都不用写。代码示例# models.py class UserInfo(models.Model): name models.CharField(verbose_name姓名, max_length16) password models.CharField(verbose_name密码, max_length64) age models.IntegerField(verbose_name年龄) gender_choices ( (1, 男), (2, 女), ) gender models.SmallIntegerField(verbose_name性别, choicesgender_choices) # views.py from django import forms from app0.models import UserInfo class MyForm(forms.ModelForm): class Meta: model UserInfo fields [name,password,age,xx] #或直接写__all__ def user_add(request): form MyForm() return render(request, user_add.html,{form:form})其他关于一些校验关于数据库搜索data_dict {mobile:19999999991,id:123} models.PrettyNum.objects.filter(**data_dict) #多个条件的筛选 models.PrettyNum.objects.filter(id12) # 等于12 models.PrettyNum.objects.filter(id__gt12) # 大于12 models.PrettyNum.objects.filter(id__gte12) # 大于等于12 models.PrettyNum.objects.filter(id__lt12) # 小于12 models.PrettyNum.objects.filter(id__lte12) # 小于等于12 models.PrettyNum.objects.filter(mobile999) # 等于 models.PrettyNum.objects.filter(mobile__startswith1999) # 筛选出以1999开头 models.PrettyNum.objects.filter(mobile__endswith999) # 筛选出以999结尾 models.PrettyNum.objects.filter(mobile__contains999) # 筛选出包含999关于分页略之后用到可以回来细看django的中间件对应项目的login模块在django中中间件Middleware是一个轻量级、底层的“插件”系统它介入 Django 的请求Request和响应Response处理过程。实际上是个类。中间件的工作流程请求阶段按照settings.py中MIDDLEWARE列表的从上到下顺序执行。响应阶段按照从下到上的逆序执行。中间件的五个核心方法在一个自定义中间件类中可以定义以下方法最常用的是前两个process_request(self, request)请求刚到达 Django还没进入 URL 路由匹配。用途登录校验、黑名单封禁。返回值如果返回None继续走下一个中间件如果返回HttpResponse直接原路返回不执行后面的视图。process_view(self, request, view_func, view_args, view_kwargs)URL 路由匹配成功但在执行具体的views函数之前。用途权限控制。process_response(self, request, response)视图函数执行完返回响应给浏览器之前。用途给响应头统一加数据、记录日志。process_exception(self, request, exception)当视图函数抛出异常时触发。用途收集错误日志、发送告警邮件。process_template_response(self, request, response)如果视图返回的对象有render方法TemplateResponse则会触发。中间件的定义在app目录下创建目录middleware在其中创建.py文件后在其中写入类而后在配置文件中的MIDDLEWARE列表中添加路径。AJAX请求对应项目的task模块AJAXAsynchronous JavaScript and XML是一种无需刷新整个网页与服务器交换数据并局部更新网页的技术。传统方式同步提交后整个页面刷新用户体验差需要重新加载整个页面AJAX 方式异步页面不刷新局部更新用户体验好只传输必要的数据项目中task模块的新建编辑删除都使用的ajax请求。图表对应项目的chart模块使用https://echarts.apache.org/handbook/zh/get-startedcv就可以了。文件上传对应项目的upload模块form methodpost enctypemultipart/form-data !--enctype写成这样就支持上传文件内容了否则只能传过去文件名称-- {% csrf_token %} input typetext nameusername input typefile nameavatar input typesubmit value提交 /formExcel上传!--html-- form methodpost enctypemultipart/form-data action/depart/muti/ {% csrf_token %} div classform-group input typefile nameexc /div input typesubmit value上传 classbtn btn-info /form#views函数 def de_muti(request): #批量上传文件 file_obj request.FILES.get(exc) #获取用户上传的文件对象 #print(type(file_obj)) #对象传递给openpyxl读取文件内容 from openpyxl import load_workbook wb load_workbook(file_obj) #可以填文件路径也可以填一个文件对象 #print(wb.sheetnames) #当新建一个 Excel 文件时系统会自动创建 3 个空白工作表sheet1,sheet2,sheet3 sheet wb.worksheets[0] #循环获取每一行数据 for row in sheet.iter_rows(min_row2): #从除表头的第一行开始 depart row[5].value exists models.Department.objects.filter(titledepart).exists() if not exists: #如果原数据库中不存在该部门就添加 models.Department.objects.create(titledepart) return redirect(/depart/list/)在django的开发过程中两个特殊的文件夹static存放静态文件的路径包括CSS、JS、项目图片。media用户上传的数据的目录。在urls.py中进行配置from django.urls import path, re_path from django.views.static import serve from django.conf import settings urlpatterns [ re_path(r^media/(?Ppath.*)$, serve, {document_root: settings.MEDIA_ROOT}, namemedia), ]在settings.py中进行配置import os MEDIA_ROOT os.path.join(BASE_DIR, media) MEDIA_URL /media/