Django银角大王武沛齐配套视频笔记,python全栈开发、pythonWeb
作者:mmseoamin日期:2023-12-11

Django

本套博客基于银角大王武沛齐的django全栈开发视频编写:传送门

如有错误或改进欢迎大家评论、私信交流指正

一、初识Django

1、Djang的安装

  • 在windos命令窗口

    win+r键,输入cmd

    pip install django
    
    • 效果:

      Django银角大王武沛齐配套视频笔记,python全栈开发、pythonWeb,image-20221023110511676,第1张

      2、Django项目

      ①创建Django项目
      • 使用Pycham创建
        Ⅰ、使用模板
        • 主页面点击左上角File->newProject
          Ⅱ、配置选项

          Django银角大王武沛齐配套视频笔记,python全栈开发、pythonWeb,image-20221023171059188,第2张

          Ⅲ、成功效果

          Django银角大王武沛齐配套视频笔记,python全栈开发、pythonWeb,image-20221023172109306,第3张

          ②项目文件
          Ⅰ、默认文件介绍
          Demo1
          ├── manage.py         【项目的管理,启动项目、创建app、数据管理】【不需要修改】【***常常用***】
          ├── templates          【存放html静态页面,后期手动创建】
          ├── static              【图片、css、js、plugins(插件)等前端样式资源,后期手动创建】
          └── Demo1
              ├── __init__.py
              ├── settings.py    【项目配置文件】          【***常常修改***】
              ├── urls.py        【URL和函数的对应关系】【***常常修改***】
              ├── asgi.py        【接收网络请求】【不要动】
              └── wsgi.py        【接收网络请求】【不要动】
          
          ③创建App文件
          • 注意:我们开发比较简洁,用不到多app,一般情况下,项目下创建1个app即可。
            Ⅰ、终端创建
            • 语法
              python manage.py startapp app文件名称
              
              • 在当前项目目录下执行manage.py文件创建App
                Ⅱ、app文件结构
                Demo1
                ├── app01
                │   ├── __init__.py
                │   ├── admin.py         【固定,不用动】django默认提供了admin后台管理。
                │   ├── apps.py          【固定,不用动】app启动类
                │   ├── migrations       【固定,不用动】数据库变更记录
                │   │   └── __init__.py
                │   ├── models.py        【**重要**】,对数据库操作,里面的oim代替了原生的Pymysql来操作数据库。
                │   ├── tests.py         【固定,不用动】单元测试
                │   └── views.py         【最常用】,列:下面执行url就会调用该文件夹的函数。
                ├── manage.py
                └── Demo1
                    ├── __init__.py
                    ├── asgi.py
                    ├── settings.py      【项目配置文件】
                    ├── urls.py          【URL->函数】
                    └── wsgi.py
                

                3、快速上手

                ①项目注册app
                Ⅰ、在项目文件夹下Settings.py文件中
                • app地址格式
                  'app文件名.apps.类名(apps.py文件中)'
                  
                  • 类名

                    Django银角大王武沛齐配套视频笔记,python全栈开发、pythonWeb,image-20221023181313400,第4张

                    • 填写信息

                      Django银角大王武沛齐配套视频笔记,python全栈开发、pythonWeb,image-20221023181016450,第5张

                      ②urls.py编写url和函数信息

                      Django银角大王武沛齐配套视频笔记,python全栈开发、pythonWeb,image-20221023182209716,第6张

                      ③views.py编写视图函数
                      • 服务器输出层

                        Django银角大王武沛齐配套视频笔记,python全栈开发、pythonWeb,image-20221023182612280,第7张

                        ④启动项目
                        Ⅰ、命令行启动
                        • 端口号可以省略默认8000
                          python manage.py runserver 8080
                          
                          • 关闭
                            ctrl+c
                            
                            Ⅱ、PyCham启动

                            Django银角大王武沛齐配套视频笔记,python全栈开发、pythonWeb,image-20221023185327679,第8张

                            ⑤访问页面

                            在浏览器访问,前面127.0.0.1.8080 是默认的,而index是要访问的页面和执行函数路径,具体见配置

                            Django银角大王武沛齐配套视频笔记,python全栈开发、pythonWeb,image-20221023190334635,第9张

                            4、访问静态页面

                            • 与快速上手步骤无异只是修改了几处位置
                              ①创建html静态页面
                              • 在app文件目录下创建一个文件夹templates,里面放置html静态页面

                              • 选中templates文件夹,右击new—File—Html,然后取文件名user_list

                              • 效果:

                                Django银角大王武沛齐配套视频笔记,python全栈开发、pythonWeb,image-20221023190927924,第10张

                                ②编写视图函数
                                • app文件夹下views.py文件

                                  Django银角大王武沛齐配套视频笔记,python全栈开发、pythonWeb,image-20221023191219600,第11张

                                  ④编写url配置文件
                                  • Demo1项目文件夹下urls.py文件

                                    Django银角大王武沛齐配套视频笔记,python全栈开发、pythonWeb,image-20221023171059188,第12张

                                    ⑤访问页面
                                    • 启动

                                    • 访问效果:

                                      Django银角大王武沛齐配套视频笔记,python全栈开发、pythonWeb,image-20221023191629221,第13张

                                      ⑥总结
                                      • 访问静态页面返回方法要使用:render()并且要导包
                                        # 调用函数访问静态页面
                                        def user_list(request):
                                            return render(request,"user_list.html")
                                        
                                        • 普通的直接使用HttpResponse()方法
                                          def index(request):
                                              return HttpResponse("欢迎使用Django")
                                          
                                          ⑥拓展templates
                                          • 页面是默认到App文件目录templates文件夹中找html文件的,但是可以配置让其到项目目录找

                                          • 添加方法:

                                            os.path.jion()
                                            

                                            5、项目文件管理

                                            ①静态页面
                                            Ⅰ、存放路径
                                            • app文件—templates文件夹
                                            • 文件夹名称必须为templates不可以修改

                                              Django银角大王武沛齐配套视频笔记,python全栈开发、pythonWeb,image-20221023193229717,第14张

                                              Ⅱ、拓展(修改存放路径)
                                              • 页面是默认到App文件目录templates文件夹中找html文件的,但是可以配置让其到项目目录找,可以查看

                                                Django银角大王武沛齐配套视频笔记,python全栈开发、pythonWeb,image-20221023192552299,第15张

                                              • 添加方法

                                                os.path.jion()
                                                
                                                ②静态文件
                                                • App目录下,名称必须为static文件

                                                • 图片、css、js、plugins(插件)等前端样式资源

                                                  Django银角大王武沛齐配套视频笔记,python全栈开发、pythonWeb,image-20221023193824517,第16张

                                                  6、Django模板语法

                                                  ①引用文件
                                                  Django独特资源路径
                                                  • 通过项目配置文件Settings.py指定文件查找路径,占位符引用资源
                                                  • 作用:

                                                    防止以后做项目需要改文件路径,可以直接通过配置文件修改

                                                    • 语法:
                                                      Django银角大王武沛齐配套视频笔记,python全栈开发、pythonWeb,第17张
                                                      
                                                      • 效果:
                                                        Django银角大王武沛齐配套视频笔记,python全栈开发、pythonWeb,第18张
                                                        
                                                        • 文件所在路径:

                                                          Django银角大王武沛齐配套视频笔记,python全栈开发、pythonWeb,image-20221023195954741,第19张

                                                        • 配置文件:

                                                          Django银角大王武沛齐配套视频笔记,python全栈开发、pythonWeb,image-20221023195843606,第20张

                                                          ②返回数据
                                                          Ⅰ、render对象
                                                          • 说明

                                                          • 导包

                                                            from django.shortcuts import render
                                                            
                                                            • 使用
                                                              def user_list(request):
                                                                  return render(request,"user_list.html")
                                                              
                                                              Ⅱ、HttpResponse对象
                                                              • 说明

                                                              • 导包

                                                                from django.shortcuts import HttpResponse
                                                                
                                                                • 使用
                                                                  def index(request):
                                                                      return HttpResponse("欢迎使用Django") # 结果输出到访问的页面
                                                                  
                                                                  ③占位符开发
                                                                  • 使用占位符让python代码可以在html文件中使用
                                                                    {% python代码 %}
                                                                    
                                                                    • views.py文件
                                                                      from django.shortcuts import render,HttpResponse
                                                                      """
                                                                      视图函数
                                                                      """
                                                                      def index(request):
                                                                          return HttpResponse("欢迎使用Django")
                                                                      # 调用函数访问静态页面
                                                                      def user_list(request):
                                                                          return render(request,"user_list.html")
                                                                      def tpl(request):
                                                                          name = "胡图图"                     # str
                                                                          roles = ["大胖子","小学生","萝卜头"]  # list
                                                                          user_info={"name":"胡图图","age":3}
                                                                          return render(request,'tpl.html',{"n1":name,"n2":roles,"n3":user_info})  # 转化
                                                                      
                                                                      • html文件
                                                                        
                                                                        
                                                                        
                                                                            
                                                                            Title
                                                                        
                                                                        
                                                                        
                                                                        
                                                                        {{ n1 }}}
                                                                        {{ n2 }}}
                                                                        {{ n2.0 }}
                                                                        {{ n2.2 }}
                                                                        {% for aaa in n2 %} aaa {% endfor %}
                                                                        {{ n3 }} {{ n3.name }} {% for foo in n3.foo %}
                                                                      • {{ foo }}
                                                                      • {% endfor %} {% if n1 == "大胖子" %}

                                                                        {% else %}

                                                                        {% endif %}
                                                                        ④案例:把python程序的数据输出到页面上

                                                                        7、请求和响应

                                                                        ①请求
                                                                        Ⅰ、获取请求方式

                                                                        获取前端的请求方式

                                                                        request.method
                                                                        

                                                                        Ⅱ、获取get请求传递的值

                                                                        返回值是字典

                                                                        # 获取在url上传递的值,get请求    url: http://127.0.0.1:8080/UrlDate/?n=1  传递了n=1
                                                                        request.GET  # 返回值:    返回的是字典
                                                                        

                                                                        Ⅲ、获取post请求

                                                                        request.POST
                                                                        
                                                                        ②响应
                                                                        • HttpResponse()
                                                                        • render()
                                                                          Ⅰ、返回字符串
                                                                            # [响应]将字符串返回给请求者
                                                                            return HttpResponse("返回内容")
                                                                          
                                                                          Ⅱ、返回一个页面,并返回模板变量
                                                                          return render(request, 'url_date.html', {"uuu": "大胖子"})
                                                                          
                                                                          • html文件
                                                                            
                                                                            
                                                                            
                                                                                
                                                                                Title
                                                                            
                                                                            
                                                                            {{ uuu }}  
                                                                            
                                                                            
                                                                            
                                                                            Ⅲ、重定向
                                                                            • 跳转页面
                                                                               # 重定项,访问次函数方法就会跳转页面
                                                                               return redirect("https://blog.csdn.net/tyx2985491138?type=blog")
                                                                              

                                                                              8、用户登录案例

                                                                              • views.py文件
                                                                                from django.shortcuts import render, HttpResponse, redirect
                                                                                """
                                                                                登录页面
                                                                                """
                                                                                def login_a(request):
                                                                                    # 用户第一次访问是以get请求,然后通过前端from表单提交是post请求,从第二次就是post请求
                                                                                    if request.method == "GET":
                                                                                        return render(request,'login.html')
                                                                                    else:
                                                                                        username = request.POST.get("user")
                                                                                        password = request.POST.get("pwd")
                                                                                        if username == 'root' and password == '123456':
                                                                                            # return HttpResponse("登录成功")
                                                                                              return redirect("https://blog.csdn.net/tyx2985491138?type=blog") # 登录成功重定向跳转页面
                                                                                        else:
                                                                                            # return HttpResponse("登录失败")
                                                                                            return render(request,'login.html',{"loginaaa":"用户名密码错误"}) # 使用模板语言让登录失败可以返回到前端
                                                                                
                                                                                • urls.py文件
                                                                                  from django.urls import path
                                                                                  from app01 import views # 导入app01中views.py文件(书写函数的文件夹)
                                                                                  urlpatterns = [
                                                                                      
                                                                                  # 用户登录案例
                                                                                      path('login/', views.login_a),
                                                                                  ]
                                                                                  
                                                                                  • html文件
                                                                                    
                                                                                    
                                                                                    
                                                                                        
                                                                                        用户登录
                                                                                    
                                                                                    
                                                                                    

                                                                                    用户登录

                                                                                    {% csrf_token %} {{ loginaaa }} 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'db1', # 数据库名字 'USER': 'root', # 用户名 'PASSWORD': 'root123', # 密码 'HOST': '127.0.0.1', # 安装了MySQL那台机器的host,本地照写 'PORT': 3306, } }
                                                                                    ③操作数据库

                                                                                    Ⅰ、创建表

                                                                                    • models.py文件中:
                                                                                      from django.db import models
                                                                                      # django创建数据库表,django会给翻译为sql语句
                                                                                      class UserInfo(models.Model):
                                                                                          name = models.CharField(max_length=32)
                                                                                          password = models.CharField(max_length=64)
                                                                                          age = models.IntegerField()
                                                                                          
                                                                                      class Role(models.Model):
                                                                                           caption = models.CharField(max_length=16)
                                                                                      
                                                                                      • 自动生成的sql语句
                                                                                        """
                                                                                           生成的sql语句
                                                                                        """
                                                                                            # 写了如上的类dajngo会自动生成如下sql语句,表面是app名+类名
                                                                                        create table app01_userinfo(
                                                                                            id bigint auto_increment primary key,
                                                                                            name VARCHAR(32),
                                                                                            password VARCHAR(64)
                                                                                            age int
                                                                                        )
                                                                                        
                                                                                        • 执行命令

                                                                                          生成sql

                                                                                          python manage.py makemigrations
                                                                                          python manage.py migrate  
                                                                                          
                                                                                          • 效果

                                                                                            Django银角大王武沛齐配套视频笔记,python全栈开发、pythonWeb,image-20221029162554808,第22张

                                                                                            Ⅱ、删除表
                                                                                            • 将Role表删掉

                                                                                            • 在创建表的基础上把models.py文件中,要删除的表的类注释或删除掉即可

                                                                                              from django.db import models
                                                                                              # django创建数据库表,django会给翻译为sql语句
                                                                                              class UserInfo(models.Model):
                                                                                                  name = models.CharField(max_length=32)
                                                                                                  password = models.CharField(max_length=64)
                                                                                                  age = models.IntegerField()
                                                                                                  
                                                                                              # class Role(models.Model):
                                                                                              #     caption = models.CharField(max_length=16)
                                                                                              
                                                                                              • 执行代码
                                                                                                python manage.py makemigrations
                                                                                                python manage.py migrate  
                                                                                                
                                                                                                Ⅲ、修改表
                                                                                                • 在创建表的基础上把models.py文件修改即可
                                                                                                  class UserInfo(models.Model):
                                                                                                      name = models.CharField(max_length=32)
                                                                                                      password = models.CharField(max_length=64)  # varchar字段
                                                                                                      # 新增列需要设置默认值
                                                                                                      age = models.IntegerField(default=2)   # 设置默认值为2
                                                                                                      data = models.IntegerField(null=True,blank=True)  # int类型,字段名data,可以为空
                                                                                                  
                                                                                                  • 然后再执行代码
                                                                                                    python manage.py makemigrations
                                                                                                    python manage.py migrate  
                                                                                                    

                                                                                                    2、增删改查

                                                                                                    ①添加数据
                                                                                                    Ⅰ、控制台添加
                                                                                                    • 语法

                                                                                                      • create()方法
                                                                                                      • 在models.py文件中
                                                                                                        类名或表名.objects.create(字段名='数据')
                                                                                                        
                                                                                                      • 列:

                                                                                                        Department.objects.create(title='销售部')
                                                                                                        UserInfo.objects.create(name="大胖子",password="110110110",age=3,data=172)
                                                                                                        
                                                                                                        • 执行代码:
                                                                                                          python manage.py makemigrations
                                                                                                          python manage.py migrate  
                                                                                                          
                                                                                                          Ⅱ、整合前端添加数据
                                                                                                          • views.py文件
                                                                                                            from app01 import models
                                                                                                            def orm(request):
                                                                                                                # 在Department文件中执行
                                                                                                                models.Department.objects.create(title="大胖子")
                                                                                                                models.Department.objects.create(title="胡图图")
                                                                                                                return HttpResponse("成功")
                                                                                                            
                                                                                                            • urls.py文件
                                                                                                              # 测试orm添加数据,访问orm后端执行sql
                                                                                                                  path('orm/',views.orm())
                                                                                                              
                                                                                                              ②删除数据
                                                                                                              Ⅰ、控制台删除
                                                                                                              • 语法delete()
                                                                                                                # 删除数据
                                                                                                                UserInfo.objects.all(id=3).delete()   # 删除UserInof表中id为3的数据
                                                                                                                Department.objects.all().delete()   # 删除全部
                                                                                                                
                                                                                                                ③获取数据
                                                                                                                • 语法

                                                                                                                  类名或表名.objects.all()   # 返回值是列表里面封装了对象,每行的对象。每一行数据都是一个对象
                                                                                                                  
                                                                                                                  • 获取全部 all()
                                                                                                                    # 获得数据
                                                                                                                    data_list = UserInfo.objects.all()   # 返回值是个列表,封装了每一行的对象
                                                                                                                    for obj in data_list:   # 使用for循环遍历,每行的对象并取出每行表的数据
                                                                                                                        print(obj.id,obj.name,obj.password,obj.age,obj.data)
                                                                                                                    
                                                                                                                    • 指定条件获取filter()
                                                                                                                      • first():获取列表第一个对象
                                                                                                                        obj = UserInfo.objects.filter(id=1).first()  # 直接返回一个对象
                                                                                                                        print(obj.id,obj.name,obj.password,obj.age,obj.data)
                                                                                                                        
                                                                                                                        ④修改数据
                                                                                                                        • update()
                                                                                                                          UserInfo.objects.filter(name="大胖子").update(age=999)
                                                                                                                          

                                                                                                                          3、综合案例:用户管理

                                                                                                                          • 创建app
                                                                                                                            python manage.py startapp app1
                                                                                                                            

                                                                                                                            三、Django开发

                                                                                                                            • 员工管理系统,基础
                                                                                                                            • Demo2

                                                                                                                              1、项目初始化

                                                                                                                              ①、删除多余的代码

                                                                                                                              Django银角大王武沛齐配套视频笔记,python全栈开发、pythonWeb,image-20221030111336543,第23张

                                                                                                                              ②、创建app

                                                                                                                              pycharm项目终端中

                                                                                                                              python manage.py startapp app1
                                                                                                                              
                                                                                                                              ③、注册app

                                                                                                                              填写的是路径

                                                                                                                              'app01.apps.App01Config'
                                                                                                                              

                                                                                                                              Django银角大王武沛齐配套视频笔记,python全栈开发、pythonWeb,image-20221030110746270,第24张

                                                                                                                              2、编写数据库

                                                                                                                              ①、设计表结构

                                                                                                                              Django银角大王武沛齐配套视频笔记,python全栈开发、pythonWeb,image-20221030120815523,第25张

                                                                                                                              ②、创建表
                                                                                                                              from django.db import models
                                                                                                                              """
                                                                                                                              部门表
                                                                                                                              """
                                                                                                                              class Department(models.Model):
                                                                                                                                  # 设置自增的,注释掉是因为pycharm创建项目会默认自动创建id
                                                                                                                                  # models.BigAutoField(verbose_name='标题',primar=True)       
                                                                                                                                  title = models.CharField(verbose_name='标题', max_length=32)  # verbose_name='标题',著名此表头的作用
                                                                                                                               
                                                                                                                              """
                                                                                                                              员工表
                                                                                                                               """
                                                                                                                              class UserInfo(models.Model):
                                                                                                                                  name = models.CharField(verbose_name='姓名', max_length=16)
                                                                                                                                  password = models.CharField(verbose_name='密码', max_length=64)  # 字符
                                                                                                                                  age = models.IntegerField(verbose_name="年龄")  # 整型
                                                                                                                                  #  max_digits:数字长度10,decimal_places:小数有两位,default默认初始值为0
                                                                                                                                  account = models.DecimalField(verbose_name='账户余额', max_digits=10, decimal_places=2, default=0)
                                                                                                                                  create_time = models.DateTimeField(verbose_name='入职时间')
                                                                                                                                  
                                                                                                                                  """外键部门表"""
                                                                                                                                  # 无约束
                                                                                                                                  # depart_id = models.BigIntegerField(verbose_name='部门表ID')   
                                                                                                                                  # 有约束
                                                                                                                                  # - to :表与哪张表关联   ,  to_fields :表与哪个字段关联
                                                                                                                                  # on_delete=models.CASCADE():表示级联删除,部门表的IT部门被删除了,所属IT部门的员工表的员工会连带删除
                                                                                                                                  # 表头名:depart_id  django会根据to_fields自动生成列名
                                                                                                                                  depart = models.ForeignKey(to=Department, to_field="id",on_delete=models.CASCADE  
                                                                                                                                  
                                                                                                                                  # 置空
                                                                                                                                  # blank=True:可以为空值,
                                                                                                                                  # on_delete=models.SET_NULL():部门表的IT部门被删除了,所属IT部门的员工的部门字段会变为null空值,即无所属部门
                                                                                                                                  # depart = models.ForeignKey(to=Department, to_fields="id", blank=True,on_delete=models.SET_NULL())
                                                                                                                                  
                                                                                                                                  """
                                                                                                                                   在django中约束。在数据库存储的是1和2,约束只能选择哪一部分
                                                                                                                                  """
                                                                                                                                  gender_choices= (
                                                                                                                                      (1, '男'),
                                                                                                                                      (2, '女')
                                                                                                                                  )
                                                                                                                                  gender = models.SmallIntegerField(verbose_name='性别',choices=gender_choices)
                                                                                                                              
                                                                                                                              ③、创建数据库
                                                                                                                              • 打开命令终端
                                                                                                                                win+r  ,输入cmd
                                                                                                                                
                                                                                                                                • 登录到mysql
                                                                                                                                  mysql -h localhost -u root -p
                                                                                                                                  
                                                                                                                                  • 创建数据库djangoDemo2,并设置编码UTF-8
                                                                                                                                     create database djangoDemo2 DEFAULT CHARSET utf8 COLLATE utf8_general_ci;
                                                                                                                                    
                                                                                                                                    • 查看数据库
                                                                                                                                      show databases;
                                                                                                                                      
                                                                                                                                      ④、修改Settings.py配置文件
                                                                                                                                      • 将原有的DATABSES全部注释掉,77行左右直接更换如下:注意修改数据库名、用户名、密码
                                                                                                                                        DATABASES = {
                                                                                                                                            'default': {
                                                                                                                                                'ENGINE': 'django.db.backends.mysql',
                                                                                                                                                'NAME': 'djangoDemo2',  # 数据库名字
                                                                                                                                                'USER': 'root',
                                                                                                                                                'PASSWORD': '1234',
                                                                                                                                                'HOST': '127.0.0.1',  # 哪台机器安装了MySQL
                                                                                                                                                'PORT': 3306, 
                                                                                                                                            }
                                                                                                                                        }
                                                                                                                                        
                                                                                                                                        ⑤、django命令生成表
                                                                                                                                        python manage.py makemigrations
                                                                                                                                        python manage.py migrate
                                                                                                                                        
                                                                                                                                        ⑥、添加数据

                                                                                                                                        控制台添加

                                                                                                                                        • 选择数据库
                                                                                                                                          USE djangodemo2
                                                                                                                                          
                                                                                                                                          • 添加数据
                                                                                                                                            insert into app_01 app1_department(title) values("销售部"),("IT部");
                                                                                                                                            

                                                                                                                                            3、导入静态文件

                                                                                                                                            • 解压放入app01目录下

                                                                                                                                              • static文件:https://wwt.lanzouy.com/iFXts0eu1vre

                                                                                                                                              • templates:https://wwt.lanzouy.com/ikXAv0eu1vtg

                                                                                                                                                4、部门管理功能

                                                                                                                                                注意导包,这个项目后面添加的功能不会把导包写出来,只会书写前端没导过的包,从而循循渐进

                                                                                                                                                ①、查询
                                                                                                                                                • views.py文件
                                                                                                                                                  from django.shortcuts import render
                                                                                                                                                  from app1 import models
                                                                                                                                                  def depart_list(request):
                                                                                                                                                      """部门列表"""
                                                                                                                                                      # 从数据库中获取全部部门信息
                                                                                                                                                      query_set = models.Department.objects.all()
                                                                                                                                                      return render(request, 'depart_list.html', {'queryset': query_set})  # 把数据库信息返回给前端遍历显示
                                                                                                                                                  
                                                                                                                                                  • urls.py
                                                                                                                                                    from django.urls import path
                                                                                                                                                    from app1 import views
                                                                                                                                                    urlpatterns = [
                                                                                                                                                        # path('admin/', admin.site.urls),
                                                                                                                                                        path('depart/list/', views.depart_list),
                                                                                                                                                    ]
                                                                                                                                                    
                                                                                                                                                    • depart_list.html文件

                                                                                                                                                      Django银角大王武沛齐配套视频笔记,python全栈开发、pythonWeb,image-20221031105103594,第26张

                                                                                                                                                      ②、新增
                                                                                                                                                      • views.py
                                                                                                                                                        from django.shortcuts import redirect
                                                                                                                                                        def depart_add(request):
                                                                                                                                                            if request.method == 'GET':
                                                                                                                                                                return render(request, 'depart_add.html')
                                                                                                                                                            # 获取用户提交过来的数据
                                                                                                                                                            title = request.POST.get("title")
                                                                                                                                                            # 保存到数据库
                                                                                                                                                            # create(数据库的列名 = 前端提交的数据)
                                                                                                                                                            models.Department.objects.create(title=title)
                                                                                                                                                            # 重定向,显示所有部门
                                                                                                                                                            return redirect('/depart/list/')
                                                                                                                                                        
                                                                                                                                                        • urls.py
                                                                                                                                                            # 新增页面
                                                                                                                                                              path('depart/add/', views.depart_add),
                                                                                                                                                          
                                                                                                                                                          • depart_add.html

                                                                                                                                                            无修改,使用即可

                                                                                                                                                            ③、删除
                                                                                                                                                            • vuews.py
                                                                                                                                                              def depart_delete(request):
                                                                                                                                                                  # 获取ID
                                                                                                                                                                  # http://127.0.0.1:8000/depart/delete/?nid=1
                                                                                                                                                                  nid = request.GET.get('nid')
                                                                                                                                                                  # 删除
                                                                                                                                                                  models.Department.objects.filter(id=nid).delete()
                                                                                                                                                                  # 重定向
                                                                                                                                                                  return redirect('/depart/list/')    # 重定向路径需要在前面也加个 / 千万要注意
                                                                                                                                                              
                                                                                                                                                              • urls.py
                                                                                                                                                                # 删除部门
                                                                                                                                                                    path('depart/delete/', views.depart_delete),
                                                                                                                                                                
                                                                                                                                                                • depart_list.html

                                                                                                                                                                  Django银角大王武沛齐配套视频笔记,python全栈开发、pythonWeb,image-20221031161850536,第27张

                                                                                                                                                                  ④、编辑
                                                                                                                                                                  • views.py
                                                                                                                                                                    def depart_edit(request, nid):
                                                                                                                                                                        if request.method == 'GET':
                                                                                                                                                                            row_update = models.Department.objects.filter(id=nid).first()
                                                                                                                                                                            print(f"被修改的部门id和名称:{row_update.id, row_update.title}")
                                                                                                                                                                            return render(request, 'depart_edit.html', {'row_update': row_update.title})
                                                                                                                                                                        # 获取用户提交的标题
                                                                                                                                                                        title = request.POST.get("title")
                                                                                                                                                                        # 根据id找到数据库中的数据并进行更新
                                                                                                                                                                        models.Department.objects.filter(id=nid).update(title=title)
                                                                                                                                                                        # 重定向返回主页面
                                                                                                                                                                        return redirect("/depart/list/")
                                                                                                                                                                    
                                                                                                                                                                    • urls.py
                                                                                                                                                                      # 编辑部门
                                                                                                                                                                          # http://127.0.0.1:8000/depart/4/edit  中间的数字用来分辨是哪个部门
                                                                                                                                                                          path('depart//edit/', views.depart_edit),
                                                                                                                                                                      
                                                                                                                                                                      • depart.html

                                                                                                                                                                        Django银角大王武沛齐配套视频笔记,python全栈开发、pythonWeb,image-20221031165430464,第28张

                                                                                                                                                                      • depart_list.html

                                                                                                                                                                        Django银角大王武沛齐配套视频笔记,python全栈开发、pythonWeb,image-20221031165509981,第29张

                                                                                                                                                                        5、django的html继承

                                                                                                                                                                        • 继承语法
                                                                                                                                                                          {% extends 'layout.html' %}   
                                                                                                                                                                          {% block content %}
                                                                                                                                                                              这里写html页面样式,子类自己独有的
                                                                                                                                                                          {% endblock %}
                                                                                                                                                                          
                                                                                                                                                                          • 作用

                                                                                                                                                                            可以显示父类的所有页面,并在其基础上进行修改,从而实现自己独特的页面,避免了重复的代码

                                                                                                                                                                            • 父类.html

                                                                                                                                                                              这个是父类的,子类继承后也会有

                                                                                                                                                                              {% block content %}{% endblock %}
                                                                                                                                                                              • 子类.html
                                                                                                                                                                                {% extends '父类.html' %} 
                                                                                                                                                                                {% block content %}
                                                                                                                                                                                    
                                                                                                                                                                                {% endblock %}
                                                                                                                                                                                

                                                                                                                                                                                四、员工表的管理功能

                                                                                                                                                                                ①、执行sql让数据库有数据

                                                                                                                                                                                登录数据库: win+r ,cmd 。mysql -u root -p

                                                                                                                                                                                选择数据库:USE dangodemo2

                                                                                                                                                                                • 执行sql添加数据
                                                                                                                                                                                  insert into app1_userinfo(name,password,age,account,create_time.grdner,depart_id) values("胡图图","110110110",7,100.64,"2022-11-1",2,1);
                                                                                                                                                                                  
                                                                                                                                                                                  insert into app1_userinfo(name,password,age,account,create_time.grdner,depart_id) values("大胖子","110110110",7,100.64,"2022-11-1",2,1);
                                                                                                                                                                                  
                                                                                                                                                                                  ②、查询
                                                                                                                                                                                  • views.py
                                                                                                                                                                                    def user_list(request):
                                                                                                                                                                                        # 获取用户全部值
                                                                                                                                                                                        user_info_list = models.UserInfo.objects.all()
                                                                                                                                                                                        # """用python语法,这里是后端的获取数据,加深理解代码 ,把对象传入前端在前端获取值  """
                                                                                                                                                                                        # for obj in user_info_list:
                                                                                                                                                                                        #     print(obj.id, obj.name, obj.account, obj.create_time.strftime("%Y-%m-%d"), obj.get_gender_display(),
                                                                                                                                                                                        #           obj.depart_id, obj.depart.title)
                                                                                                                                                                                        #     """重点"""
                                                                                                                                                                                        #     obj.create_time.strftime("%Y-%m-%d") # strftime("%Y-%m-%d"):表显示年月日
                                                                                                                                                                                        #     obj.get_gender_display()  # 创建员工表时给其定义了,存储数据库1代表是男,2代表是女。这个方法意思是获取规则
                                                                                                                                                                                        #     obj.depart.title  # 根据id获取,链表的title字段的数据,depart:是models.py文件创建员工表的字段返回值,title则是外键部门表的部门名称字段
                                                                                                                                                                                        return render(request, 'user_list.html', {'user_info_list': user_info_list})
                                                                                                                                                                                    
                                                                                                                                                                                    • urls.py
                                                                                                                                                                                        # 员工管理
                                                                                                                                                                                          path('user/list/', views.user_list),
                                                                                                                                                                                      
                                                                                                                                                                                      • user_list.html

                                                                                                                                                                                        Django银角大王武沛齐配套视频笔记,python全栈开发、pythonWeb,image-20221101112103417,第30张

                                                                                                                                                                                      • obj.get_gender_display()

                                                                                                                                                                                        • 创建员工表时给其定义了,存储数据库1代表是男,2代表是女。这个方法意思是获取规则,从而更好的显示在数据库

                                                                                                                                                                                        • 员工表:Django银角大王武沛齐配套视频笔记,python全栈开发、pythonWeb,image-20221101112440388,第31张

                                                                                                                                                                                        • 因为存储在数据库的数据是1和2

                                                                                                                                                                                        • **obj.depart.title **

                                                                                                                                                                                          • 因为外键去获取另一个表的值,title是部门表的部门名称,通过外键查询

                                                                                                                                                                                          • 员工表:Django银角大王武沛齐配套视频笔记,python全栈开发、pythonWeb,image-20221101112946227,第32张

                                                                                                                                                                                          • 效果:

                                                                                                                                                                                            Django银角大王武沛齐配套视频笔记,python全栈开发、pythonWeb,image-20221101113400113,第33张

                                                                                                                                                                                          • 员工表在数据库的样子

                                                                                                                                                                                            Django银角大王武沛齐配套视频笔记,python全栈开发、pythonWeb,image-20221101113441314,第34张

                                                                                                                                                                                            ③、添加(原始方法)
                                                                                                                                                                                            • 原始方法:麻烦
                                                                                                                                                                                              - 用户提交数据没有校验
                                                                                                                                                                                              - 错误,页面上不能显示错误提示	
                                                                                                                                                                                              - 页面上每一个字段都需要我们写一遍
                                                                                                                                                                                              - 关联的数据,需要我们手动循环一个一个获取
                                                                                                                                                                                              
                                                                                                                                                                                              • views.py
                                                                                                                                                                                                def user_add(request):
                                                                                                                                                                                                    # 访问页面是get请求,提交数据是post请求
                                                                                                                                                                                                    if request.method == "GET":
                                                                                                                                                                                                        context = {  
                                                                                                                                                                                                            'gender_choices': models.UserInfo.gender_choices,   # 获取所有性别对应的中文
                                                                                                                                                                                                            'depart_list': models.Department.objects.all()      # 获取所有部门
                                                                                                                                                                                                        }
                                                                                                                                                                                                        return render(request, 'user_add.html', context)  # 将字典返回到前端
                                                                                                                                                                                                    # post请求,通过前端表单name值获取每个表单数据
                                                                                                                                                                                                    user = request.POST.get("ruser")
                                                                                                                                                                                                    pwd = request.POST.get("pwd")
                                                                                                                                                                                                    age = request.POST.get("age")
                                                                                                                                                                                                    ac = request.POST.get("ac")
                                                                                                                                                                                                    ctime = request.POST.get("ctime")
                                                                                                                                                                                                    gender = request.POST.get("gd")
                                                                                                                                                                                                    dp = request.POST.get("dp")
                                                                                                                                                                                                    # 将数据添加到数据库中
                                                                                                                                                                                                    models.UserInfo.objects.create(name=user, password=pwd, age=age, account=ac, create_time=ctime, gender=gender,depart_id=dp)
                                                                                                                                                                                                    # 添加成功返回用户列表页面
                                                                                                                                                                                                    return redirect("/user/list")
                                                                                                                                                                                                
                                                                                                                                                                                                • urls.py
                                                                                                                                                                                                  # 添加
                                                                                                                                                                                                      path('user/add/', views.user_add),
                                                                                                                                                                                                  
                                                                                                                                                                                                  • user_add.html
                                                                                                                                                                                                    {% extends 'layout.html' %}
                                                                                                                                                                                                    {% block content %}
                                                                                                                                                                                                        

                                                                                                                                                                                                    新建用户

                                                                                                                                                                                                    {% csrf_token %}
                                                                                                                                                                                                    {% endblock %}
                                                                                                                                                                                                    • 效果:

                                                                                                                                                                                                      Django银角大王武沛齐配套视频笔记,python全栈开发、pythonWeb,image-20221101170023952,第35张

                                                                                                                                                                                                      ④、组件
                                                                                                                                                                                                      • Form组件(小简便)
                                                                                                                                                                                                      • ModelForm组件(最简便)
                                                                                                                                                                                                        Ⅰ、From组件

                                                                                                                                                                                                        简化重复书写表单

                                                                                                                                                                                                        • views.py
                                                                                                                                                                                                          class MyForm(Form):
                                                                                                                                                                                                              user = forms.CharField(widget=forms.Input)
                                                                                                                                                                                                              pwd = form.CharFiled(widget=forms.Input)
                                                                                                                                                                                                              email = form.CharFiled(widget=forms.Input)
                                                                                                                                                                                                              account = form.CharFiled(widget=forms.Input)
                                                                                                                                                                                                              create_time = form.CharFiled(widget=forms.Input)
                                                                                                                                                                                                              depart = form.CharFiled(widget=forms.Input)
                                                                                                                                                                                                              gender = form.CharFiled(widget=forms.Input)
                                                                                                                                                                                                          def user_add(request):
                                                                                                                                                                                                              if request.method == "GET":
                                                                                                                                                                                                                  form = MyForm()
                                                                                                                                                                                                                  return render(request, 'user_add.html',{"form":form})
                                                                                                                                                                                                          
                                                                                                                                                                                                          • user_add.html
                                                                                                                                                                                                            {{ form.user }} {{ form.pwd }} {{ form.email }}

                                                                                                                                                                                                            使用循环加工

                                                                                                                                                                                                            {% for field in form%} {{ field }} {% endfor %}
                                                                                                                                                                                                            Ⅱ、ModeForm组件(推荐)

                                                                                                                                                                                                            再Form组件的基础上进一步简化

                                                                                                                                                                                                            • views.py
                                                                                                                                                                                                              class MyForm(ModelForm):   # 只有这里有区别
                                                                                                                                                                                                                  xxx = form.CharField*("...")    # 自定义字段,也支持自定义生成一个字段
                                                                                                                                                                                                                  class Meta:
                                                                                                                                                                                                                      model = UserInfo   # UserInfo是创建员工表的类名
                                                                                                                                                                                                                      fields = ["name","password","age","account","create_time","depart","gender","xxx"]   # 列表内写的是字段返回值,字段名
                                                                                                                                                                                                              def user_add(request):
                                                                                                                                                                                                                  if request.method == "GET":
                                                                                                                                                                                                                      form = MyForm()
                                                                                                                                                                                                                      return render(request, 'user_add.html',{"form":form})
                                                                                                                                                                                                              
                                                                                                                                                                                                              • models.py
                                                                                                                                                                                                                class UserInfo(models.Model):
                                                                                                                                                                                                                    """ 员工表 """
                                                                                                                                                                                                                    name = models.CharField(verbose_name="姓名", max_length=16)
                                                                                                                                                                                                                    password = models.CharField(verbose_name="密码", max_length=64)
                                                                                                                                                                                                                    age = models.IntegerField(verbose_name="年龄")
                                                                                                                                                                                                                    account = models.DecimalField(verbose_name="账户余额", max_digits=10, decimal_places=2, default=0)
                                                                                                                                                                                                                    create_time = models.DateTimeField(verbose_name="入职时间")
                                                                                                                                                                                                                    depart = models.ForeignKey(to="Department", to_field="id", on_delete=models.CASCADE)
                                                                                                                                                                                                                    gender_choices = (
                                                                                                                                                                                                                        (1, "男"),
                                                                                                                                                                                                                        (2, "女"),
                                                                                                                                                                                                                    )
                                                                                                                                                                                                                    gender = models.SmallIntegerField(verbose_name="性别", choices=gender_choices)
                                                                                                                                                                                                                
                                                                                                                                                                                                                • user_add.html
                                                                                                                                                                                                                  {% for field in form%} {{ field }} {% endfor %}
                                                                                                                                                                                                                  ⑤、ModelForm组件实现添加
                                                                                                                                                                                                                  • views.py
                                                                                                                                                                                                                    """
                                                                                                                                                                                                                    组件实现添加用户
                                                                                                                                                                                                                    """
                                                                                                                                                                                                                    from django import forms
                                                                                                                                                                                                                      # 使用组件
                                                                                                                                                                                                                    class UserModelForm(forms.ModelForm):
                                                                                                                                                                                                                        name = forms.CharField(min_length=3, label="用户名")  # 设置name表单接收数据最小值为3
                                                                                                                                                                                                                        class Meta:
                                                                                                                                                                                                                            model = models.UserInfo
                                                                                                                                                                                                                            fields = ["name", "password", "age", "account", "create_time", "gender", "depart"]
                                                                                                                                                                                                                            # 定义表单的class属性
                                                                                                                                                                                                                            # widgets = {
                                                                                                                                                                                                                            #     "name": forms.TextInput(attrs={"class": "form-control"}),
                                                                                                                                                                                                                            #     "password": forms.TextInput(attrs={"class": "form-control"}),
                                                                                                                                                                                                                            # }
                                                                                                                                                                                                                            # 简化上面注释的代码
                                                                                                                                                                                                                            # 批量生成,让字段加样式
                                                                                                                                                                                                                            def __init__(self, *args, **kwargs):
                                                                                                                                                                                                                                super().__init__(*args, **kwargs)
                                                                                                                                                                                                                                # 循环获取所有插件
                                                                                                                                                                                                                                for name, field in self.fields.items():  # 这里的name是字段名
                                                                                                                                                                                                                                    # if name == "password":   # 让password这个字段不加class
                                                                                                                                                                                                                                    #     continue
                                                                                                                                                                                                                                    field.widgets.attrs = {"class": "form-control", "placeholder": field.labels}
                                                                                                                                                                                                                    def user_model_form_add(request):
                                                                                                                                                                                                                        if request.method == "GET":
                                                                                                                                                                                                                            form = UserModelForm()
                                                                                                                                                                                                                            return render(request, 'user_model_form_add.html', {'form': form})
                                                                                                                                                                                                                        # 用户使用post提交数据,数据校验
                                                                                                                                                                                                                        form = UserModelForm(data=request.POST)
                                                                                                                                                                                                                        if form.is_valid():
                                                                                                                                                                                                                            # 逐一校验,数据合法存储入数据库
                                                                                                                                                                                                                            # print(form.changed_data)
                                                                                                                                                                                                                            form.save()
                                                                                                                                                                                                                            return redirect('/user/list/')
                                                                                                                                                                                                                        else:
                                                                                                                                                                                                                            print(form.errors)  # 将错误信息打印出来
                                                                                                                                                                                                                            return render(request, 'user_model_form_add.html', {'form': form})
                                                                                                                                                                                                                    
                                                                                                                                                                                                                    • urls.py
                                                                                                                                                                                                                       # 组件实现添加
                                                                                                                                                                                                                          path('user/model/form/add', views.user_model_form_add)
                                                                                                                                                                                                                      
                                                                                                                                                                                                                      • setting.py设置中文

                                                                                                                                                                                                                        • LANGUAGE_CODE = 'zh-hans' 
                                                                                                                                                                                                                          

                                                                                                                                                                                                                          Django银角大王武沛齐配套视频笔记,python全栈开发、pythonWeb,image-20221102125023026,第36张

                                                                                                                                                                                                                        • user_model_form_add.html

                                                                                                                                                                                                                          {% extends 'layout.html' %}
                                                                                                                                                                                                                          {% block content %}
                                                                                                                                                                                                                              

                                                                                                                                                                                                                          新建用户

                                                                                                                                                                                                                          {% csrf_token %} { form.name.label }}: {{ form.name }}--> { form.password.label }}: {{ form.password }}--> {% for field in form %}
                                                                                                                                                                                                                          {{ field }} {{ field.errors.0 }}
                                                                                                                                                                                                                          {% endfor %}
                                                                                                                                                                                                                          {% endblock %}
                                                                                                                                                                                                                          • 效果:

                                                                                                                                                                                                                            Django银角大王武沛齐配套视频笔记,python全栈开发、pythonWeb,image-20221102130039718,第37张

                                                                                                                                                                                                                          • models.py

                                                                                                                                                                                                                            from django.db import models
                                                                                                                                                                                                                            # Create your models here.
                                                                                                                                                                                                                            class Department(models.Model):
                                                                                                                                                                                                                                """部门表"""
                                                                                                                                                                                                                                # models.BigAutoField(verbose_name='标题',primar=True)       # 设置自增的,注释掉是因为pycharm创建项目会默认自动创建
                                                                                                                                                                                                                                title = models.CharField(verbose_name='标题', max_length=32)  # verbose_name='标题',著名此表头的作用
                                                                                                                                                                                                                                # 类似于to.string方法
                                                                                                                                                                                                                                def __str__(self):
                                                                                                                                                                                                                                    return self.title
                                                                                                                                                                                                                            class UserInfo(models.Model):
                                                                                                                                                                                                                                """员工表"""
                                                                                                                                                                                                                                name = models.CharField(verbose_name='姓名', max_length=16)
                                                                                                                                                                                                                                password = models.CharField(verbose_name='密码', max_length=64)  # 字符
                                                                                                                                                                                                                                age = models.IntegerField(verbose_name="年龄")  # 整型
                                                                                                                                                                                                                                account = models.DecimalField(verbose_name='账户余额', max_digits=10, decimal_places=2, default=0)
                                                                                                                                                                                                                                create_time = models.DateTimeField(verbose_name='入职时间')
                                                                                                                                                                                                                              
                                                                                                                                                                                                                                depart = models.ForeignKey(verbose_name='部门', to=Department, to_field="id", on_delete=models.CASCADE)
                                                                                                                                                                                                                               
                                                                                                                                                                                                                                gender_choices = (
                                                                                                                                                                                                                                    (1, '男'),
                                                                                                                                                                                                                                    (2, '女')
                                                                                                                                                                                                                                )
                                                                                                                                                                                                                                gender = models.SmallIntegerField(verbose_name='性别', choices=gender_choices)
                                                                                                                                                                                                                            
                                                                                                                                                                                                                            ⑥编辑

                                                                                                                                                                                                                            使用组件

                                                                                                                                                                                                                            Ⅰ、思路
                                                                                                                                                                                                                            • 点击编辑用户,跳转页面并携带需要编辑的那一行的id get
                                                                                                                                                                                                                            • 根据携带过来的id显示一些默认信息(从数据库获取) get
                                                                                                                                                                                                                            • 提交:post
                                                                                                                                                                                                                              • 错误提示、数据校验
                                                                                                                                                                                                                              • 数据库更新数据
                                                                                                                                                                                                                                Ⅱ、实现
                                                                                                                                                                                                                                • views.py
                                                                                                                                                                                                                                  def user_edit(request, nid):
                                                                                                                                                                                                                                      row_object = models.UserInfo.objects.filter(id=nid).first()  # 用于告诉ModelForm是要修改哪一行数据,而不是添加
                                                                                                                                                                                                                                      # 根据id获取要编辑的那一行数据,从而将原来的值显示在页面上
                                                                                                                                                                                                                                      if request.method == 'GET':
                                                                                                                                                                                                                                          # row_object = models.UserInfo.objects.filter(id=nid).first()
                                                                                                                                                                                                                                          form = UserModelForm(instance=row_object)
                                                                                                                                                                                                                                          name = row_object.name
                                                                                                                                                                                                                                          return render(request, 'user_edit.html', {'form': form, 'name': name})  # 因为form是字典所以可以直接返回,不用大括号
                                                                                                                                                                                                                                      # post提交表单请求,并数据校验
                                                                                                                                                                                                                                      # row_object = models.UserInfo.objects.filter(id=nid).first()  # 用于告诉ModelForm是要修改哪一行数据,而不是添加
                                                                                                                                                                                                                                      form = UserModelForm(data=request.POST, instance=row_object)
                                                                                                                                                                                                                                      if form.is_valid():
                                                                                                                                                                                                                                          form.save()  # 数据合法存储入数据库
                                                                                                                                                                                                                                          return redirect('/user/list/')
                                                                                                                                                                                                                                      else:
                                                                                                                                                                                                                                          return render(request, 'user_edit.html', {'form': form})
                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                  • urls.py
                                                                                                                                                                                                                                      # 编辑
                                                                                                                                                                                                                                        path('user//edit/', views.user_edit),
                                                                                                                                                                                                                                    
                                                                                                                                                                                                                                    • user_edit.html

                                                                                                                                                                                                                                      需要自己创建

                                                                                                                                                                                                                                      {% extends 'layout.html' %}
                                                                                                                                                                                                                                      {% block content %}
                                                                                                                                                                                                                                          

                                                                                                                                                                                                                                      编辑{{ name }}用户

                                                                                                                                                                                                                                      {% csrf_token %} { form.name.label }}: {{ form.name }}--> { form.password.label }}: {{ form.password }}--> {% for field in form %}
                                                                                                                                                                                                                                      {{ field }} {{ field.errors.0 }}
                                                                                                                                                                                                                                      {% endfor %}
                                                                                                                                                                                                                                      {% endblock %}
                                                                                                                                                                                                                                      • user_list.html

                                                                                                                                                                                                                                        修改一些内容

                                                                                                                                                                                                                                        Django银角大王武沛齐配套视频笔记,python全栈开发、pythonWeb,image-20221103001721199,第38张

                                                                                                                                                                                                                                      • 效果

                                                                                                                                                                                                                                        Django银角大王武沛齐配套视频笔记,python全栈开发、pythonWeb,image-20221103001909304,第39张

                                                                                                                                                                                                                                        ⑦删除
                                                                                                                                                                                                                                        • views.py
                                                                                                                                                                                                                                          """
                                                                                                                                                                                                                                          删除用户
                                                                                                                                                                                                                                          """
                                                                                                                                                                                                                                          def user_delete(request):
                                                                                                                                                                                                                                              # 获取ID
                                                                                                                                                                                                                                              # http://127.0.0.1:8000/depart/delete/?nid=1
                                                                                                                                                                                                                                              nid = request.GET.get('nid')  # 获取删除按钮通过表单传达过来的nid值
                                                                                                                                                                                                                                              print(nid)
                                                                                                                                                                                                                                              models.UserInfo.objects.filter(id=nid).delete()
                                                                                                                                                                                                                                              return redirect('/user/list/')
                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                          • urls.py
                                                                                                                                                                                                                                            # 删除
                                                                                                                                                                                                                                                path('user/delete/', views.user_delete),
                                                                                                                                                                                                                                            
                                                                                                                                                                                                                                            • user_list.html

                                                                                                                                                                                                                                              Django银角大王武沛齐配套视频笔记,python全栈开发、pythonWeb,image-20221103003504460,第40张

                                                                                                                                                                                                                                              五、靓号管理

                                                                                                                                                                                                                                              ①创建表
                                                                                                                                                                                                                                              class PrettyNum(models.Model):
                                                                                                                                                                                                                                                  mobile = models.CharField(verbose_name="手机号", max_length=11)
                                                                                                                                                                                                                                                  # 想要允许为空 null=True ,blank = True
                                                                                                                                                                                                                                                  price = models.IntegerField(verbose_name="价格")
                                                                                                                                                                                                                                                  # 级别
                                                                                                                                                                                                                                                  level_choice = (
                                                                                                                                                                                                                                                      (1, '1级'),
                                                                                                                                                                                                                                                      (2, '2级'),
                                                                                                                                                                                                                                                      (3, '3级'),
                                                                                                                                                                                                                                                      (4, '4级'),
                                                                                                                                                                                                                                                  )
                                                                                                                                                                                                                                                  level = models.SmallIntegerField(verbose_name="级别", choices=level_choice, default=1)  # 小整型
                                                                                                                                                                                                                                                  status_choices = (
                                                                                                                                                                                                                                                      (1, '已占用'),
                                                                                                                                                                                                                                                      (2, '未占用'),
                                                                                                                                                                                                                                                  )
                                                                                                                                                                                                                                                  status = models.SmallIntegerField(verbose_name="级别", choices=status_choices, default=2)
                                                                                                                                                                                                                                              
                                                                                                                                                                                                                                              ②靓号列表
                                                                                                                                                                                                                                              • 将ID、号码、价格、级别(中文)、状态(中文)、操作(编辑和删除)展现出来

                                                                                                                                                                                                                                              • views.py

                                                                                                                                                                                                                                                def admin_list(request):
                                                                                                                                                                                                                                                    # order_by()设置排序,select * from 表名 order by level desc
                                                                                                                                                                                                                                                    queryset = models.PrettyNum.objects.all().order_by("-level")  # 加-则表示desc,不加-则表示level
                                                                                                                                                                                                                                                    return render(requesret, 'admin_list.html', {'queryset': queryset})
                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                • urls.py
                                                                                                                                                                                                                                                   # 靓号列表主页面
                                                                                                                                                                                                                                                      path('admin/list/', views.admin_list),
                                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                  • admin_list.html
                                                                                                                                                                                                                                                    {% extends 'layout.html ' %}
                                                                                                                                                                                                                                                    {% block content %}
                                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                    靓号列表
                                                                                                                                                                                                                                                    {% for obj in queryset %} {% endfor %}
                                                                                                                                                                                                                                                    ID 号码 价格 级别 状态 操作
                                                                                                                                                                                                                                                    {{ obj.id }} {{ obj.mobile }} {{ obj.price }} {{ obj.get_level_display }} {{ obj.get_status_display }} 编辑 删除
                                                                                                                                                                                                                                                    {% endblock %}
                                                                                                                                                                                                                                                    ④添加
                                                                                                                                                                                                                                                    • 通过正则表达式校验数据

                                                                                                                                                                                                                                                    • views.py

                                                                                                                                                                                                                                                      from django.core.validators import RegexValidator
                                                                                                                                                                                                                                                      from django.core.exceptions import ValidationError
                                                                                                                                                                                                                                                      class UserModForm2(forms.ModelForm):
                                                                                                                                                                                                                                                          # 验证:方法1
                                                                                                                                                                                                                                                          # mobile = forms.CharField(
                                                                                                                                                                                                                                                          #     label="手机号",
                                                                                                                                                                                                                                                          #     validators=[RegexValidator(r'^\d{11}$', '手机号必须为11位数')]  # 使用正则表达式对其加强校验
                                                                                                                                                                                                                                                          # )
                                                                                                                                                                                                                                                          class Meta:
                                                                                                                                                                                                                                                              model = models.PrettyNum  # 选择表
                                                                                                                                                                                                                                                              fields = ["mobile", "price", "level", "status"]  # 这个是自己选哪些字段
                                                                                                                                                                                                                                                              # fields = "__all__"   # 这个是所有字段
                                                                                                                                                                                                                                                              # exclude = ['level']  # 这个是排除哪个字段
                                                                                                                                                                                                                                                          """加载样式"""
                                                                                                                                                                                                                                                          # def __init__(self, *args, **kwargs):
                                                                                                                                                                                                                                                          #     super().__init__(*args, **kwargs)
                                                                                                                                                                                                                                                          #     # 循环获取所有插件
                                                                                                                                                                                                                                                          #     for name, field in self.fields.items():  # 这里的name是字段名
                                                                                                                                                                                                                                                          #         # if name == "password":   # 让password这个字段不加class
                                                                                                                                                                                                                                                          #         #     continue
                                                                                                                                                                                                                                                          #         # 设置生成的表单class值为"form-control"
                                                                                                                                                                                                                                                          #         field.widgets.attrs = {"class": "form-control", "placeholder": field.labels}
                                                                                                                                                                                                                                                          # 验证:方法2
                                                                                                                                                                                                                                                          def clean_mobile(self):
                                                                                                                                                                                                                                                              txt_mobile = self.cleaned_data["mobile"]  # 获取"mobile"字段用户输入的值
                                                                                                                                                                                                                                                              if len(txt_mobile) != 11:
                                                                                                                                                                                                                                                                  # 验证不通过
                                                                                                                                                                                                                                                                  raise ValidationError("格式错误")
                                                                                                                                                                                                                                                              # 验证通过,用户输入的值返回
                                                                                                                                                                                                                                                              return txt_mobile
                                                                                                                                                                                                                                                      def admin_add(request):
                                                                                                                                                                                                                                                          if request.method == 'GET':
                                                                                                                                                                                                                                                              form = UserModForm2()
                                                                                                                                                                                                                                                              return render(request, 'admin_add.html', {'form': form})
                                                                                                                                                                                                                                                          # post请求
                                                                                                                                                                                                                                                          form = UserModForm2(data=request.POST)
                                                                                                                                                                                                                                                          if form.is_valid():  # 一个一个校验数据
                                                                                                                                                                                                                                                              form.save()  # 添加进入数据库
                                                                                                                                                                                                                                                              return redirect('/admin/list/')
                                                                                                                                                                                                                                                          else:
                                                                                                                                                                                                                                                              print(form.errors)  # 打印错误信息
                                                                                                                                                                                                                                                              return render(request, 'admin_add.html', {'form': form})
                                                                                                                                                                                                                                                      
                                                                                                                                                                                                                                                      • urls.py
                                                                                                                                                                                                                                                            # 添加
                                                                                                                                                                                                                                                            path('admin/add/', views.admin_add),
                                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                        • admin_add.html
                                                                                                                                                                                                                                                          {% extends 'layout.html' %}
                                                                                                                                                                                                                                                           {% block content %}
                                                                                                                                                                                                                                                                 

                                                                                                                                                                                                                                                          添加靓号

                                                                                                                                                                                                                                                          {% csrf_token %} {% for field in form %}
                                                                                                                                                                                                                                                          {{ field }} {{ field.errors.0 }}
                                                                                                                                                                                                                                                          {% endfor %}
                                                                                                                                                                                                                                                          {% endblock %}
                                                                                                                                                                                                                                                          ⑤编辑
                                                                                                                                                                                                                                                          • 电话号码不可编辑,但还是要显示到页面上

                                                                                                                                                                                                                                                          • 点击编辑后会携带靓号的id到后端从而修改

                                                                                                                                                                                                                                                          • views.py

                                                                                                                                                                                                                                                            def admin_edit(request, nid):
                                                                                                                                                                                                                                                                row_object = models.PrettyNum.objects.filter(id=nid).first()
                                                                                                                                                                                                                                                                if request.method == "GET":
                                                                                                                                                                                                                                                                    form = UserModForm2(instance=row_object)
                                                                                                                                                                                                                                                                    return render(request, 'admin_edit.html', {'form': form})
                                                                                                                                                                                                                                                                form = UserModForm2(data=request.POST, instance=row_object)
                                                                                                                                                                                                                                                                if form.is_valid():
                                                                                                                                                                                                                                                                    form.save()
                                                                                                                                                                                                                                                                    return redirect('/admin/list')
                                                                                                                                                                                                                                                                else:
                                                                                                                                                                                                                                                                    return render(request, 'admin_edit.html', {'form': form})
                                                                                                                                                                                                                                                            
                                                                                                                                                                                                                                                            • urls.py
                                                                                                                                                                                                                                                                # 编辑
                                                                                                                                                                                                                                                                  path('admin//edit/', views.admin_edit),
                                                                                                                                                                                                                                                              
                                                                                                                                                                                                                                                              • admin_edit.html
                                                                                                                                                                                                                                                                {% extends 'layout.html' %}
                                                                                                                                                                                                                                                                {% block content %}
                                                                                                                                                                                                                                                                    

                                                                                                                                                                                                                                                                编辑靓号

                                                                                                                                                                                                                                                                {% csrf_token %} {% for field in form %}
                                                                                                                                                                                                                                                                {{ field }} {{ field.errors.0 }}
                                                                                                                                                                                                                                                                {% endfor %}
                                                                                                                                                                                                                                                                {% endblock %}
                                                                                                                                                                                                                                                                ⑥删除
                                                                                                                                                                                                                                                                • views.py
                                                                                                                                                                                                                                                                  def admin_delete(request):
                                                                                                                                                                                                                                                                      nid = request.GET.get('nid')   # 前端的?nid = {{obj.id}} ,?是占位符代表给nid赋值
                                                                                                                                                                                                                                                                      models.PrettyNum.objects.filter(id=nid).delete()
                                                                                                                                                                                                                                                                      return redirect('/admin/list')
                                                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                                  • urls.py
                                                                                                                                                                                                                                                                    # 删除
                                                                                                                                                                                                                                                                        path('admin/delete/', views.admin_delete)
                                                                                                                                                                                                                                                                    
                                                                                                                                                                                                                                                                    • admin_list.html

                                                                                                                                                                                                                                                                      Django银角大王武沛齐配套视频笔记,python全栈开发、pythonWeb,image-20221104174406074,第41张

                                                                                                                                                                                                                                                                      ⑦搜索查询
                                                                                                                                                                                                                                                                      • 手机号搜索
                                                                                                                                                                                                                                                                        Ⅰ、views.py
                                                                                                                                                                                                                                                                        • 修改原主页函数文件
                                                                                                                                                                                                                                                                          def admin_list(request):
                                                                                                                                                                                                                                                                              """查询所有"""
                                                                                                                                                                                                                                                                              # order_by()设置排序,select * from 表名 order by level desc
                                                                                                                                                                                                                                                                              # queryset = models.PrettyNum.objects.all().order_by("-price")  # 加-则表示正序,不加-则表示倒叙,按价格从高到低
                                                                                                                                                                                                                                                                              # return render(request, 'admin_list.html', {'queryset': queryset})
                                                                                                                                                                                                                                                                              """搜索查询"""
                                                                                                                                                                                                                                                                              data_dict = {}
                                                                                                                                                                                                                                                                              search_data = request.GET.get('q', "")
                                                                                                                                                                                                                                                                              if search_data:
                                                                                                                                                                                                                                                                                  data_dict["mobile__contains"] = search_data
                                                                                                                                                                                                                                                                              queryset = models.PrettyNum.objects.filter(**data_dict).order_by("-price")  # 按条件查询
                                                                                                                                                                                                                                                                              return render(request, 'admin_list.html', {'queryset': queryset, 'search_data': search_data})
                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                          Ⅱ、urls.py
                                                                                                                                                                                                                                                                          • 不改变
                                                                                                                                                                                                                                                                             # 靓号列表主页面
                                                                                                                                                                                                                                                                                path('admin/list/', views.admin_list),
                                                                                                                                                                                                                                                                            
                                                                                                                                                                                                                                                                            Ⅲ、admin_list.html
                                                                                                                                                                                                                                                                            • 将原主页修改

                                                                                                                                                                                                                                                                            • 搜索框样式是bootstrap:官网https://v3.bootcss.com/ 样式包(bootstrap-3.4.1):https://wwt.lanzouy.com/iYMpj0f7fgze

                                                                                                                                                                                                                                                                            • 导入样式包(bootstrap-3.4.1)

                                                                                                                                                                                                                                                                               
                                                                                                                                                                                                                                                                              
                                                                                                                                                                                                                                                                              Django银角大王武沛齐配套视频笔记,python全栈开发、pythonWeb,image-20221104192428406,第42张
                                                                                                                                                                                                                                                                              • 代码
                                                                                                                                                                                                                                                                                ⑧分页查询
                                                                                                                                                                                                                                                                                • 给数据库添加300条数据

                                                                                                                                                                                                                                                                                  写在views.py的admin_list函数中,访问即可给数据库添加300条数据

                                                                                                                                                                                                                                                                                  # 添加300条数据
                                                                                                                                                                                                                                                                                      for i in range(300):
                                                                                                                                                                                                                                                                                          models.PrettyNum.objects.create(mobile="16656678912", price=10, level=1, status=1)
                                                                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                                                  Ⅰ、sql语法:
                                                                                                                                                                                                                                                                                   queryset = models.PrettyNum.objects.filter(**data_dict).order_by("-price")[初始分页索引:结尾id]
                                                                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                                                  Ⅱ、views.py
                                                                                                                                                                                                                                                                                  def admin_list(request):
                                                                                                                                                                                                                                                                                      """查询所有"""
                                                                                                                                                                                                                                                                                      # order_by()设置排序,select * from 表名 order by level desc
                                                                                                                                                                                                                                                                                      # queryset = models.PrettyNum.objects.all().order_by("-price")  # 加-则表示正序,不加-则表示倒叙,按价格从高到低
                                                                                                                                                                                                                                                                                      # return render(request, 'admin_list.html', {'queryset': queryset})
                                                                                                                                                                                                                                                                                       """搜索查询"""
                                                                                                                                                                                                                                                                                      data_dict = {}
                                                                                                                                                                                                                                                                                      search_data = request.GET.get('q', "")
                                                                                                                                                                                                                                                                                      if search_data:
                                                                                                                                                                                                                                                                                          data_dict["mobile__contains"] = search_data
                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                      """分页"""
                                                                                                                                                                                                                                                                                      # 获取get请求传递的值,page默认值为1,当前页码
                                                                                                                                                                                                                                                                                      x = int(request.GET.get('p', 1))   # 搜索页码的值
                                                                                                                                                                                                                                                                                      if x > 1:
                                                                                                                                                                                                                                                                                          page = x
                                                                                                                                                                                                                                                                                      page = int(request.GET.get('page', 1))   # 页码输入的当前页码
                                                                                                                                                                                                                                                                                      # 当前页码,根据用户想要访问的页面,计算出起止位置
                                                                                                                                                                                                                                                                                      page_size = 10  # 显示10条数据
                                                                                                                                                                                                                                                                                      start = (page - 1) * page_size
                                                                                                                                                                                                                                                                                      end = page * page_size
                                                                                                                                                                                                                                                                                      # 按条件查询
                                                                                                                                                                                                                                                                                      queryset = models.PrettyNum.objects.filter(**data_dict).order_by("-price")[start:end]
                                                                                                                                                                                                                                                                                      # 数据总条数
                                                                                                                                                                                                                                                                                      total_count = models.PrettyNum.objects.filter(**data_dict).order_by("-price").count()
                                                                                                                                                                                                                                                                                      
                                                                                                                                                                                                                                                                                      """页码"""
                                                                                                                                                                                                                                                                                      # 总页码 = 数据总条数/每页显示数据条数
                                                                                                                                                                                                                                                                                      total_page_count, div = divmod(total_count, page_size)
                                                                                                                                                                                                                                                                                      # if div:
                                                                                                                                                                                                                                                                                      #     total_page_count += 1
                                                                                                                                                                                                                                                                                      # 计算,显示出当前页的前五页和后五页
                                                                                                                                                                                                                                                                                      plus = 5  # 显示前后页码条数
                                                                                                                                                                                                                                                                                      if total_page_count <= 2 * plus + 1:  # 小于11页
                                                                                                                                                                                                                                                                                          # 数据库数据较少没有超过十一页,把所有页码显示
                                                                                                                                                                                                                                                                                          start_page = 1
                                                                                                                                                                                                                                                                                          end_page = total_page_count
                                                                                                                                                                                                                                                                                      else:
                                                                                                                                                                                                                                                                                          # 数据库数据大于11页数据
                                                                                                                                                                                                                                                                                          # 当前页小于5(小极值)
                                                                                                                                                                                                                                                                                          if page <= plus:  # page是前端用户传入要访问的页数
                                                                                                                                                                                                                                                                                              start_page = 1
                                                                                                                                                                                                                                                                                              end_page = 2 * plus + 1
                                                                                                                                                                                                                                                                                          else:
                                                                                                                                                                                                                                                                                              # 当前页+显示条数>总页码
                                                                                                                                                                                                                                                                                              if (page + plus) > total_page_count:
                                                                                                                                                                                                                                                                                                  start_page = total_page_count - 2 * plus
                                                                                                                                                                                                                                                                                                  end_page = total_page_count
                                                                                                                                                                                                                                                                                              else:
                                                                                                                                                                                                                                                                                                  start_page = page - plus  # 当前页减5
                                                                                                                                                                                                                                                                                                  end_page = page + plus  # 后五页
                                                                                                                                                                                                                                                                                      # 自动生成页码(前端样式)
                                                                                                                                                                                                                                                                                      page_str_list = []
                                                                                                                                                                                                                                                                                      # 上一页
                                                                                                                                                                                                                                                                                      if page > 1:
                                                                                                                                                                                                                                                                                          prev = '
                                                                                                                                                                                                                                                                                • 上一页
                                                                                                                                                                                                                                                                                • '.format(page - 1) # 当前页减一 else: prev = '
                                                                                                                                                                                                                                                                                • 上一页
                                                                                                                                                                                                                                                                                • '.format(1) page_str_list.append(prev) # for i in range(1, total_page_count + 1): # 初始页面和总页码 for i in range(start_page, end_page + 1): # +1 因为数据库搜索出来数据总数会少1 if i == page: # 判断是当前页的话给其添加样式 elc = '
                                                                                                                                                                                                                                                                                • {}
                                                                                                                                                                                                                                                                                • '.format(i, i) else: elc = '
                                                                                                                                                                                                                                                                                • {}
                                                                                                                                                                                                                                                                                • '.format(i, i) page_str_list.append(elc) # 将添加进列表中 # 下一页 if page < total_page_count: prev = '
                                                                                                                                                                                                                                                                                • 下一页
                                                                                                                                                                                                                                                                                • '.format(page + 1) # 当前页加1 else: prev = '
                                                                                                                                                                                                                                                                                • 下一页
                                                                                                                                                                                                                                                                                • '.format(total_page_count) # 总页码 page_str_list.append(prev) # 尾页 one = '
                                                                                                                                                                                                                                                                                • 尾页
                                                                                                                                                                                                                                                                                • '.format(total_page_count) page_str_list.append(one) # 使用mark_safe包裹就可以将字符串转化成html,在导包的前提下from django.utils.safestring import mark_safe page_string = mark_safe("".join(page_str_list)) return render(request, 'admin_list.html', {'queryset': queryset, 'search_data': search_data, "page_string": page_string})
                                                                                                                                                                                                                                                                                  • urls.py

                                                                                                                                                                                                                                                                                    不做更改

                                                                                                                                                                                                                                                                                    Ⅲ、admin_list.html
                                                                                                                                                                                                                                                                                    
                                                                                                                                                                                                                                                                                            
                                                                                                                                                                                                                                                                                      {#
                                                                                                                                                                                                                                                                                    • 1
                                                                                                                                                                                                                                                                                    • #} {#
                                                                                                                                                                                                                                                                                    • 2
                                                                                                                                                                                                                                                                                    • #} {#
                                                                                                                                                                                                                                                                                    • 3
                                                                                                                                                                                                                                                                                    • #} {#
                                                                                                                                                                                                                                                                                    • 4
                                                                                                                                                                                                                                                                                    • #} {#
                                                                                                                                                                                                                                                                                    • 5
                                                                                                                                                                                                                                                                                    • #} {{ page_string }}
                                                                                                                                                                                                                                                                                    Ⅳ、效果:

                                                                                                                                                                                                                                                                                    Django银角大王武沛齐配套视频笔记,python全栈开发、pythonWeb,image-20221106230715505,第43张

                                                                                                                                                                                                                                                                                    ⑨、使用封装简化分页代码(封装分页)
                                                                                                                                                                                                                                                                                    Ⅰ、views.py
                                                                                                                                                                                                                                                                                    def admin_list(request):
                                                                                                                                                                                                                                                                                        """查询所有"""
                                                                                                                                                                                                                                                                                        # order_by()设置排序,select * from 表名 order by level desc
                                                                                                                                                                                                                                                                                        # queryset = models.PrettyNum.objects.all().order_by("-price")  # 加-则表示正序,不加-则表示倒叙,按价格从高到低
                                                                                                                                                                                                                                                                                        # return render(request, 'admin_list.html', {'queryset': queryset})
                                                                                                                                                                                                                                                                                        """搜索查询"""
                                                                                                                                                                                                                                                                                        data_dict = {}
                                                                                                                                                                                                                                                                                        search_data = request.GET.get('q', "")
                                                                                                                                                                                                                                                                                        if search_data:
                                                                                                                                                                                                                                                                                            data_dict["mobile__contains"] = search_data
                                                                                                                                                                                                                                                                                        """分页"""
                                                                                                                                                                                                                                                                                        from app1.utils.pagination import Pagination
                                                                                                                                                                                                                                                                                        # 按条件查询
                                                                                                                                                                                                                                                                                        # queryset = models.PrettyNum.objects.filter(**data_dict).order_by("-price")[page_object.start: page_object.end]
                                                                                                                                                                                                                                                                                        queryset = models.PrettyNum.objects.filter(**data_dict).order_by("-price")
                                                                                                                                                                                                                                                                                        page_object = Pagination(request, queryset)  # 获取自定义组件类
                                                                                                                                                                                                                                                                                        page_queryset = page_object.page_queryset  # 获取分页完的数据
                                                                                                                                                                                                                                                                                        page_string = page_object.html()  # 生成的页码
                                                                                                                                                                                                                                                                                        context = {
                                                                                                                                                                                                                                                                                            "queryset": page_queryset,
                                                                                                                                                                                                                                                                                            "search_date": search_data,  # 分完页的数据
                                                                                                                                                                                                                                                                                            "page_string": page_string  # 生成的页码
                                                                                                                                                                                                                                                                                        }
                                                                                                                                                                                                                                                                                        return render(request, 'admin_list.html', context)  # 使用组件后
                                                                                                                                                                                                                                                                                    
                                                                                                                                                                                                                                                                                    Ⅱ、pagination.py
                                                                                                                                                                                                                                                                                    • 在app1中创建utils文件夹里面创建paginaion.py

                                                                                                                                                                                                                                                                                    • 将页码生成、数据获取、前端页码生成封装到pagination.py文件中Pagination类中

                                                                                                                                                                                                                                                                                      """
                                                                                                                                                                                                                                                                                      自定义分页组件
                                                                                                                                                                                                                                                                                      """
                                                                                                                                                                                                                                                                                      from django.utils.safestring import mark_safe
                                                                                                                                                                                                                                                                                      from django import forms
                                                                                                                                                                                                                                                                                      class Pagination(object):
                                                                                                                                                                                                                                                                                          def __init__(self, request, queryset, page_size=10, page_param="page", plus=5):
                                                                                                                                                                                                                                                                                              """
                                                                                                                                                                                                                                                                                              :param request: 请求的对象
                                                                                                                                                                                                                                                                                              :param queryset:查询的数据,符合条件的数据对这个进行分页处理
                                                                                                                                                                                                                                                                                              :param page_size:每页显示多条数据
                                                                                                                                                                                                                                                                                              :param page_param:在URL中传递获取分页的参数,列如:/etty/list/https://blog.csdn.net/tyx2985491138/article/details/131528972?page=12
                                                                                                                                                                                                                                                                                              :param plus:显示当前页的,前、后几页(页码)
                                                                                                                                                                                                                                                                                              """
                                                                                                                                                                                                                                                                                              import copy
                                                                                                                                                                                                                                                                                              query_dict = copy.deepcopy(request.GET)
                                                                                                                                                                                                                                                                                              query_dict._mutable = True
                                                                                                                                                                                                                                                                                              self.query_dict = query_dict
                                                                                                                                                                                                                                                                                              self.page_param = page_param
                                                                                                                                                                                                                                                                                              page = request.GET.get(page_param, "1")  # 把request获取前端get请求的方法,封装到page中,页码
                                                                                                                                                                                                                                                                                              if page.isdecimal():  # 处理页码,判断页码是否是正常传入数字,而不是字符串
                                                                                                                                                                                                                                                                                                  page = int(page)
                                                                                                                                                                                                                                                                                              else:
                                                                                                                                                                                                                                                                                                  page = 1  # 前端传入页码不规范,则默认为1
                                                                                                                                                                                                                                                                                              self.page = page
                                                                                                                                                                                                                                                                                              self.page_size = page_size
                                                                                                                                                                                                                                                                                              # 计算分页页码,sql值
                                                                                                                                                                                                                                                                                              self.start = (page - 1) * page_size
                                                                                                                                                                                                                                                                                              self.end = page * page_size
                                                                                                                                                                                                                                                                                              self.page_queryset = queryset[self.start: self.end]  # 分完页的数据
                                                                                                                                                                                                                                                                                              # total_count = models.PrettyNum.objects.filter(**data_dict).order_by("-price").count()
                                                                                                                                                                                                                                                                                              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  # 显示前后页码条数
                                                                                                                                                                                                                                                                                          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('
                                                                                                                                                                                                                                                                                    • 首页
                                                                                                                                                                                                                                                                                    • '.format(self.query_dict.urlencode())) # 上一页 if self.page > 1: self.query_dict.setlist(self.page_param, [self.page - 1]) prev = '
                                                                                                                                                                                                                                                                                    • 上一页
                                                                                                                                                                                                                                                                                    • '.format(self.query_dict.urlencode()) else: self.query_dict.setlist(self.page_param, [1]) prev = '
                                                                                                                                                                                                                                                                                    • 上一页
                                                                                                                                                                                                                                                                                    • '.format(self.query_dict.urlencode()) page_str_list.append(prev) # 页面 for i in range(start_page, end_page + 1): self.query_dict.setlist(self.page_param, [i]) if i == self.page: ele = '
                                                                                                                                                                                                                                                                                    • {}
                                                                                                                                                                                                                                                                                    • '.format(self.query_dict.urlencode(), i) else: ele = '
                                                                                                                                                                                                                                                                                    • {}
                                                                                                                                                                                                                                                                                    • '.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 = '
                                                                                                                                                                                                                                                                                    • 下一页
                                                                                                                                                                                                                                                                                    • '.format(self.query_dict.urlencode()) else: self.query_dict.setlist(self.page_param, [self.total_page_count]) prev = '
                                                                                                                                                                                                                                                                                    • 下一页
                                                                                                                                                                                                                                                                                    • '.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('
                                                                                                                                                                                                                                                                                    • 尾页
                                                                                                                                                                                                                                                                                    • '.format(self.query_dict.urlencode())) search_string = """
                                                                                                                                                                                                                                                                                    • """ page_str_list.append(search_string) page_string = mark_safe("".join(page_str_list)) return page_string
                                                                                                                                                                                                                                                                                      Ⅲ、效果

                                                                                                                                                                                                                                                                                      Django银角大王武沛齐配套视频笔记,python全栈开发、pythonWeb,image-20221107161937082,第44张

                                                                                                                                                                                                                                                                                      六、拓展功能(1)

                                                                                                                                                                                                                                                                                      1、时间插件

                                                                                                                                                                                                                                                                                      • 插件链接:https://wwt.lanzouy.com/imuOd0fe3opc

                                                                                                                                                                                                                                                                                      • 用于美化、简化入职时间填写,可以直接通过点击xuan’ze

                                                                                                                                                                                                                                                                                        2、分模块开发

                                                                                                                                                                                                                                                                                        • 将views.py中用户管理、部门管理、靓号管理分为三个py文件,代码不用改,只需改urls.py中函数路径

                                                                                                                                                                                                                                                                                        • views文件夹

                                                                                                                                                                                                                                                                                          Django银角大王武沛齐配套视频笔记,python全栈开发、pythonWeb,image-20221109113859782,第45张

                                                                                                                                                                                                                                                                                        • urls.py

                                                                                                                                                                                                                                                                                          重点在导包,和函数路径

                                                                                                                                                                                                                                                                                          from django.contrib import admin
                                                                                                                                                                                                                                                                                          from django.urls import path
                                                                                                                                                                                                                                                                                          from app1 import views
                                                                                                                                                                                                                                                                                          from app1.views import admin, list, user   # 导入views文件
                                                                                                                                                                                                                                                                                          urlpatterns = [
                                                                                                                                                                                                                                                                                              # path('admin/', admin.site.urls),
                                                                                                                                                                                                                                                                                              # 部门管理
                                                                                                                                                                                                                                                                                              # 主页面、列表页面
                                                                                                                                                                                                                                                                                              path('depart/list/',list.depart_list),
                                                                                                                                                                                                                                                                                              # 新增部门
                                                                                                                                                                                                                                                                                              path('depart/add/', list.depart_add),
                                                                                                                                                                                                                                                                                              # 删除部门
                                                                                                                                                                                                                                                                                              path('depart/delete/', list.depart_delete),
                                                                                                                                                                                                                                                                                              # 编辑部门
                                                                                                                                                                                                                                                                                              # http://127.0.0.1:8000/depart/4/edit  中间的数字用来分辨是哪个部门
                                                                                                                                                                                                                                                                                              path('depart//edit/', list.depart_edit),
                                                                                                                                                                                                                                                                                              # 员工管理
                                                                                                                                                                                                                                                                                              path('user/list/', user.user_list),
                                                                                                                                                                                                                                                                                              # 添加
                                                                                                                                                                                                                                                                                              path('user/add/', user.user_add),
                                                                                                                                                                                                                                                                                              # 组件实现添加
                                                                                                                                                                                                                                                                                              path('user/model/form/add', user.user_model_form_add),
                                                                                                                                                                                                                                                                                              # 编辑
                                                                                                                                                                                                                                                                                              path('user//edit/', user.user_edit),
                                                                                                                                                                                                                                                                                              # 删除
                                                                                                                                                                                                                                                                                              path('user/delete/', user.user_delete),
                                                                                                                                                                                                                                                                                              # 靓号管理
                                                                                                                                                                                                                                                                                              # 靓号列表主页面
                                                                                                                                                                                                                                                                                              path('admin/list/', admin.admin_list),
                                                                                                                                                                                                                                                                                              # 添加
                                                                                                                                                                                                                                                                                              path('admin/add/', admin.admin_add),
                                                                                                                                                                                                                                                                                              # 编辑
                                                                                                                                                                                                                                                                                              path('admin//edit/', admin.admin_edit),
                                                                                                                                                                                                                                                                                              # 删除
                                                                                                                                                                                                                                                                                              path('admin/delete/', admin.admin_delete)
                                                                                                                                                                                                                                                                                          ]
                                                                                                                                                                                                                                                                                          

                                                                                                                                                                                                                                                                                          七、管理员

                                                                                                                                                                                                                                                                                          1、创建数据库

                                                                                                                                                                                                                                                                                          • models.py
                                                                                                                                                                                                                                                                                            class VIP(models.Model):
                                                                                                                                                                                                                                                                                                username = models.CharField(verbose_name="用户名", max_length=32)
                                                                                                                                                                                                                                                                                                password = models.CharField(verbose_name="密码", max_length=64)
                                                                                                                                                                                                                                                                                            
                                                                                                                                                                                                                                                                                            • 执行代码
                                                                                                                                                                                                                                                                                              python manage.py makemigrations
                                                                                                                                                                                                                                                                                              python manage.py migrate
                                                                                                                                                                                                                                                                                              

                                                                                                                                                                                                                                                                                              2、管理员列表

                                                                                                                                                                                                                                                                                              • VIP.py

                                                                                                                                                                                                                                                                                                在views文件夹中创建VIP.py文件

                                                                                                                                                                                                                                                                                                from django.shortcuts import render, redirect
                                                                                                                                                                                                                                                                                                from app1 import models
                                                                                                                                                                                                                                                                                                # 分页自定义模块
                                                                                                                                                                                                                                                                                                from app1.utils.pagination import Pagination
                                                                                                                                                                                                                                                                                                """
                                                                                                                                                                                                                                                                                                管理员列表
                                                                                                                                                                                                                                                                                                """
                                                                                                                                                                                                                                                                                                def VIP_list(request):
                                                                                                                                                                                                                                                                                                    # 搜索功能
                                                                                                                                                                                                                                                                                                    # 构造搜索条件
                                                                                                                                                                                                                                                                                                    data_dict = {}
                                                                                                                                                                                                                                                                                                    search_data = request.GET.get('q', "")
                                                                                                                                                                                                                                                                                                    if search_data:
                                                                                                                                                                                                                                                                                                        data_dict["username__contains"] = search_data
                                                                                                                                                                                                                                                                                                    # 根据条件去数据库获取
                                                                                                                                                                                                                                                                                                    queryset = models.VIP.objects.filter(**data_dict)
                                                                                                                                                                                                                                                                                                    # 分页
                                                                                                                                                                                                                                                                                                    page_object = Pagination(request, queryset)
                                                                                                                                                                                                                                                                                                    queryset = {
                                                                                                                                                                                                                                                                                                        'queryset': queryset,
                                                                                                                                                                                                                                                                                                        'page_string': page_object.html(),
                                                                                                                                                                                                                                                                                                        'search_data': search_data,
                                                                                                                                                                                                                                                                                                    }
                                                                                                                                                                                                                                                                                                    return render(request, 'VIP_list.html', queryset)
                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                • urls.py
                                                                                                                                                                                                                                                                                                  # 主页面
                                                                                                                                                                                                                                                                                                  path('VIP/list', VIP.VIP_list),
                                                                                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                                                                  • VIP.html
                                                                                                                                                                                                                                                                                                    {% extends 'layout.html ' %}
                                                                                                                                                                                                                                                                                                    {% block content %}
                                                                                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                                                                    添加管理员
                                                                                                                                                                                                                                                                                                    管理员账户列表
                                                                                                                                                                                                                                                                                                    {% for obj in queryset %} {% endfor %}
                                                                                                                                                                                                                                                                                                    ID 号码 密码 重置密码 操作
                                                                                                                                                                                                                                                                                                    {{ obj.id }} {{ obj.username }} ******** 重置密码 编辑 删除
                                                                                                                                                                                                                                                                                                      {{ page_string }}
                                                                                                                                                                                                                                                                                                    {% endblock %}

                                                                                                                                                                                                                                                                                                    3、添加

                                                                                                                                                                                                                                                                                                    • 重点:密码校验

                                                                                                                                                                                                                                                                                                    • VIP.py

                                                                                                                                                                                                                                                                                                      views文件夹下

                                                                                                                                                                                                                                                                                                      from django import forms
                                                                                                                                                                                                                                                                                                      from django.core.exceptions import ValidationError
                                                                                                                                                                                                                                                                                                      from app1.utils.bootstrap import BootStrapModeForm  # 创建input框
                                                                                                                                                                                                                                                                                                      from app1.utils.encrypt import md5  # 加密
                                                                                                                                                                                                                                                                                                      # 使用组件创建input框
                                                                                                                                                                                                                                                                                                      class VIPModelForm(BootStrapModeForm):  # 或者继承forms.Modelform
                                                                                                                                                                                                                                                                                                          # 额外生成一个确认密码表单
                                                                                                                                                                                                                                                                                                          confirm_password = forms.CharField(
                                                                                                                                                                                                                                                                                                              label="确认密码",
                                                                                                                                                                                                                                                                                                              widget=forms.PasswordInput(render_value=True)  # 输入密码时候不会显示密码,render_value=True表示密码错了密码不需要重新输入
                                                                                                                                                                                                                                                                                                          )
                                                                                                                                                                                                                                                                                                          class Meta:
                                                                                                                                                                                                                                                                                                              model = models.VIP
                                                                                                                                                                                                                                                                                                              fields = ["username", "password", "confirm_password"]
                                                                                                                                                                                                                                                                                                              # 给原有字段,生成的表单添加额外修饰
                                                                                                                                                                                                                                                                                                              widgets = {
                                                                                                                                                                                                                                                                                                                  "password": forms.PasswordInput(render_value=True)
                                                                                                                                                                                                                                                                                                              }
                                                                                                                                                                                                                                                                                                          # 加密
                                                                                                                                                                                                                                                                                                          def clean_password(self):
                                                                                                                                                                                                                                                                                                              pwd = self.cleaned_data.get("password")
                                                                                                                                                                                                                                                                                                              return md5(pwd)  # 调用加密函数给input框的数据加密,并将加完密的函数返回,则下面方法获取该表单都是加密了的
                                                                                                                                                                                                                                                                                                          # 钩子函数,获取指定字段用户输入的值
                                                                                                                                                                                                                                                                                                          def clean_confirm_password(self):
                                                                                                                                                                                                                                                                                                              #   form.cleaned_data  获取校验成功后所有数据,具体看上面定义的clean_confirm_password钩子函数
                                                                                                                                                                                                                                                                                                              password = self.cleaned_data.get("password")  # 因为上面给表单加密了,所以这里获取的值是加密的值
                                                                                                                                                                                                                                                                                                              confirm = md5(self.cleaned_data.get("confirm_password"))  # 获取确认用户表单,用户输入的值,并使其加密从而可以使密文和密文进行比较
                                                                                                                                                                                                                                                                                                              if confirm != password:
                                                                                                                                                                                                                                                                                                                  raise ValidationError("密码不一致")  # 抛出异常到前端,需要导包
                                                                                                                                                                                                                                                                                                              return confirm  # 这里返回的值就是存储入数据库的值
                                                                                                                                                                                                                                                                                                      def VIP_add(request):
                                                                                                                                                                                                                                                                                                          title = "添加管理员"
                                                                                                                                                                                                                                                                                                          if request.method == "GET":
                                                                                                                                                                                                                                                                                                              form = VIPModelForm()
                                                                                                                                                                                                                                                                                                              return render(request, 'change.html', {"title": title, "form": form})
                                                                                                                                                                                                                                                                                                          # post请求校验数据,并跳转主页面
                                                                                                                                                                                                                                                                                                          form = VIPModelForm(data=request.POST)
                                                                                                                                                                                                                                                                                                          if form.is_valid():
                                                                                                                                                                                                                                                                                                              # 上面的钩子函数也是校验数据
                                                                                                                                                                                                                                                                                                              form.save()
                                                                                                                                                                                                                                                                                                              return redirect('/VIP/list')
                                                                                                                                                                                                                                                                                                          # 有错误信息,则还是在添加页面,并可以看到错误信息
                                                                                                                                                                                                                                                                                                          return render(request, 'change.html', {"title": title, "form": form})
                                                                                                                                                                                                                                                                                                      
                                                                                                                                                                                                                                                                                                      • urls.py
                                                                                                                                                                                                                                                                                                            # 添加管理员
                                                                                                                                                                                                                                                                                                            path('VIP/add', VIP.VIP_add),
                                                                                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                                                                        • change.html
                                                                                                                                                                                                                                                                                                          • 因为添加的页面文件都差不多一样,所以可以使用一个文件,只是在需要不同的地方给其自定义
                                                                                                                                                                                                                                                                                                            
                                                                                                                                                                                                                                                                                                            {% extends 'layout.html' %}
                                                                                                                                                                                                                                                                                                             {% block content %}
                                                                                                                                                                                                                                                                                                                   

                                                                                                                                                                                                                                                                                                            {{ title }}

                                                                                                                                                                                                                                                                                                            {% csrf_token %} {% for field in form %}
                                                                                                                                                                                                                                                                                                            {{ field }} {{ field.errors.0 }}
                                                                                                                                                                                                                                                                                                            {% endfor %}
                                                                                                                                                                                                                                                                                                            {% endblock %}
                                                                                                                                                                                                                                                                                                            • encrypt.py
                                                                                                                                                                                                                                                                                                              • 自定义的密码校验工具类,放在app01/utils/下
                                                                                                                                                                                                                                                                                                              • 密码和确认密码比较也是使用加密后的密码进行比较
                                                                                                                                                                                                                                                                                                              • 原理是将密码嵌入到django配置文件随机生成的字符串中,具体见第8行代码
                                                                                                                                                                                                                                                                                                                import hashlib
                                                                                                                                                                                                                                                                                                                from django.conf import settings
                                                                                                                                                                                                                                                                                                                """
                                                                                                                                                                                                                                                                                                                给字符串加密
                                                                                                                                                                                                                                                                                                                """
                                                                                                                                                                                                                                                                                                                def md5(data_string):
                                                                                                                                                                                                                                                                                                                    obj = hashlib.md5(settings.SECRET_KEY.encode('utf-8'))   # SECRET_KEY是django的配置文件Setting随机生成的一个字符串
                                                                                                                                                                                                                                                                                                                    obj.update(data_string.encode('utf-8'))
                                                                                                                                                                                                                                                                                                                    return obj.hexdigest()
                                                                                                                                                                                                                                                                                                                

                                                                                                                                                                                                                                                                                                                4、编辑

                                                                                                                                                                                                                                                                                                                • VIP.py

                                                                                                                                                                                                                                                                                                                  views文件夹子文件

                                                                                                                                                                                                                                                                                                                  class VIPEditModelForm(BootStrapModeForm):
                                                                                                                                                                                                                                                                                                                      class Meta:
                                                                                                                                                                                                                                                                                                                          model = models.VIP
                                                                                                                                                                                                                                                                                                                          fields = ["username"]  # 只允许修改用户名
                                                                                                                                                                                                                                                                                                                  def VIP_edit(request, nid):
                                                                                                                                                                                                                                                                                                                      title = "编辑管理员"
                                                                                                                                                                                                                                                                                                                      row_object = models.VIP.objects.filter(id=nid).first()
                                                                                                                                                                                                                                                                                                                      if not row_object:  # 判断是否有这个用户,没有就证明id为错误的
                                                                                                                                                                                                                                                                                                                          return redirect('/VIP/list')
                                                                                                                                                                                                                                                                                                                      if request.method == "GET":
                                                                                                                                                                                                                                                                                                                          form = VIPEditModelForm(instance=row_object)  # 将原来的值显示在页面上
                                                                                                                                                                                                                                                                                                                          return render(request, 'change.html', {"title": title, "form": form})
                                                                                                                                                                                                                                                                                                                      # 提交数据
                                                                                                                                                                                                                                                                                                                      form = VIPEditModelForm(data=request.POST, instance=row_object)
                                                                                                                                                                                                                                                                                                                      if form.is_valid():
                                                                                                                                                                                                                                                                                                                          form.save()
                                                                                                                                                                                                                                                                                                                          return redirect('/VIP/list')
                                                                                                                                                                                                                                                                                                                      return render(request, 'change.html', {"title": title, "form": form})
                                                                                                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                                                                                  • urls.py
                                                                                                                                                                                                                                                                                                                      # 编辑
                                                                                                                                                                                                                                                                                                                        path('VIP//edit/', VIP.VIP_edit),
                                                                                                                                                                                                                                                                                                                    
                                                                                                                                                                                                                                                                                                                    • change.html
                                                                                                                                                                                                                                                                                                                      • 和如上添加管理员使用同一个html,只是有一些区别在views.py文件(VIP.py)中

                                                                                                                                                                                                                                                                                                                        5、删除

                                                                                                                                                                                                                                                                                                                        • VIP.py
                                                                                                                                                                                                                                                                                                                          def VIP_delete(request):
                                                                                                                                                                                                                                                                                                                              nid = request.GET.get('nid')
                                                                                                                                                                                                                                                                                                                              models.VIP.objects.filter(id=nid).delete()
                                                                                                                                                                                                                                                                                                                              return redirect('/VIP/list')
                                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                          • urls.py
                                                                                                                                                                                                                                                                                                                               # 删除
                                                                                                                                                                                                                                                                                                                                path('VIP/delete/', VIP.VIP_delete),
                                                                                                                                                                                                                                                                                                                            
                                                                                                                                                                                                                                                                                                                            • 注意把管理员的主页面按钮路径改一下

                                                                                                                                                                                                                                                                                                                              6、重置密码

                                                                                                                                                                                                                                                                                                                              • views.py
                                                                                                                                                                                                                                                                                                                                # 使用组件创建input框
                                                                                                                                                                                                                                                                                                                                class VIPresetModelForm(BootStrapModeForm):  # 或者继承forms.Modelform
                                                                                                                                                                                                                                                                                                                                    # 额外生成一个确认密码表单
                                                                                                                                                                                                                                                                                                                                    confirm_password = forms.CharField(
                                                                                                                                                                                                                                                                                                                                        label="确认密码",
                                                                                                                                                                                                                                                                                                                                        widget=forms.PasswordInput(render_value=True)  # 输入密码时候不会显示密码,render_value=True表示密码错了密码不需要重新输入
                                                                                                                                                                                                                                                                                                                                    )
                                                                                                                                                                                                                                                                                                                                    class Meta:
                                                                                                                                                                                                                                                                                                                                        model = models.VIP
                                                                                                                                                                                                                                                                                                                                        fields = ["password", "confirm_password"]
                                                                                                                                                                                                                                                                                                                                        # 给原有字段,生成的表单添加额外修饰
                                                                                                                                                                                                                                                                                                                                        widgets = {
                                                                                                                                                                                                                                                                                                                                            "password": forms.PasswordInput(render_value=True)
                                                                                                                                                                                                                                                                                                                                        }
                                                                                                                                                                                                                                                                                                                                    # 加密
                                                                                                                                                                                                                                                                                                                                    def clean_password(self):
                                                                                                                                                                                                                                                                                                                                        pwd = self.cleaned_data.get("password")
                                                                                                                                                                                                                                                                                                                                        md5_pwd = md5(pwd)  # 调用加密函数给input框的数据加密,并将加完密的函数返回,则下面方法获取该表单都是加密了的
                                                                                                                                                                                                                                                                                                                                        # 去数据库校验之前密码和新输入的密码是否一致
                                                                                                                                                                                                                                                                                                                                        exists = models.VIP.objects.filter(id=self.instance.pk, password=md5_pwd)  # 返回的是布尔值
                                                                                                                                                                                                                                                                                                                                        if exists:
                                                                                                                                                                                                                                                                                                                                            raise ValidationError("密码使用过,请尝试重新输入密码")
                                                                                                                                                                                                                                                                                                                                        return md5_pwd
                                                                                                                                                                                                                                                                                                                                    # 钩子函数,获取指定字段用户输入的值
                                                                                                                                                                                                                                                                                                                                    def clean_confirm_password(self):
                                                                                                                                                                                                                                                                                                                                        #   form.cleaned_data  获取校验成功后所有数据,具体看上面定义的clean_confirm_password钩子函数
                                                                                                                                                                                                                                                                                                                                        password = self.cleaned_data.get("password")  # 因为上面给表单加密了,所以这里获取的值是加密的值
                                                                                                                                                                                                                                                                                                                                        confirm = md5(self.cleaned_data.get("confirm_password"))  # 获取确认用户表单,用户输入的值,并使其加密从而可以使密文和密文进行比较
                                                                                                                                                                                                                                                                                                                                        if confirm != password:
                                                                                                                                                                                                                                                                                                                                            raise ValidationError("密码不一致")  # 抛出异常到前端,需要导包
                                                                                                                                                                                                                                                                                                                                        return confirm  # 这里返回的值就是存储入数据库的值
                                                                                                                                                                                                                                                                                                                                def VIP_reset(request, nid):
                                                                                                                                                                                                                                                                                                                                    row_object = models.VIP.objects.filter(id=nid).first()
                                                                                                                                                                                                                                                                                                                                    if not row_object:
                                                                                                                                                                                                                                                                                                                                        return redirect('/VIP/list')
                                                                                                                                                                                                                                                                                                                                    title = "重置用户:{} 密码".format(row_object.username)
                                                                                                                                                                                                                                                                                                                                    if request.method == 'GET':
                                                                                                                                                                                                                                                                                                                                        form = VIPresetModelForm()
                                                                                                                                                                                                                                                                                                                                        return render(request, 'change.html', {"title": title, "form": form})
                                                                                                                                                                                                                                                                                                                                    # 提交数据
                                                                                                                                                                                                                                                                                                                                    form = VIPresetModelForm(data=request.POST, instance=row_object)
                                                                                                                                                                                                                                                                                                                                    if form.is_valid():
                                                                                                                                                                                                                                                                                                                                        form.save()
                                                                                                                                                                                                                                                                                                                                        return redirect('/VIP/list')
                                                                                                                                                                                                                                                                                                                                    return render(request, 'change.html', {"title": title, "form": form})
                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                • urls.py
                                                                                                                                                                                                                                                                                                                                   # 重置密码
                                                                                                                                                                                                                                                                                                                                      path('VIP//reset/', VIP.VIP_reset),
                                                                                                                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                                                                                                  • BootStrap.py

                                                                                                                                                                                                                                                                                                                                    自定义的工具包,因为重置密码使用的是form而不是ModelForm所以使用继承改装一下

                                                                                                                                                                                                                                                                                                                                    from django import forms
                                                                                                                                                                                                                                                                                                                                    """
                                                                                                                                                                                                                                                                                                                                    添加样式,实际是给每个表单创建class属性
                                                                                                                                                                                                                                                                                                                                    """
                                                                                                                                                                                                                                                                                                                                    class BootStrap:
                                                                                                                                                                                                                                                                                                                                        def __int__(self, *args, **kwargs):
                                                                                                                                                                                                                                                                                                                                            super().__init__(*args, **kwargs)
                                                                                                                                                                                                                                                                                                                                            # 循环Modelform中所有字段,给每个字段的插件设置
                                                                                                                                                                                                                                                                                                                                            for name, field in self.field.items():
                                                                                                                                                                                                                                                                                                                                                # 字段中有属性,保留原来的属性,没有属性才增加
                                                                                                                                                                                                                                                                                                                                                if field.widget.attrs:
                                                                                                                                                                                                                                                                                                                                                    field.widget.attrs["class"] = "form-control"
                                                                                                                                                                                                                                                                                                                                                    field.widget.attrs["placeholder"] = field.label
                                                                                                                                                                                                                                                                                                                                                else:
                                                                                                                                                                                                                                                                                                                                                    field.widget.attrs = {
                                                                                                                                                                                                                                                                                                                                                        "class": "form-control",
                                                                                                                                                                                                                                                                                                                                                        "placeholder": field.label
                                                                                                                                                                                                                                                                                                                                                    }
                                                                                                                                                                                                                                                                                                                                    class BootStrapModeForm(BootStrap, forms.ModelForm):
                                                                                                                                                                                                                                                                                                                                        pass
                                                                                                                                                                                                                                                                                                                                    class BootStrapForm(BootStrap, forms.Form):
                                                                                                                                                                                                                                                                                                                                        pass
                                                                                                                                                                                                                                                                                                                                    
                                                                                                                                                                                                                                                                                                                                    • change.html

                                                                                                                                                                                                                                                                                                                                      八、拓展功能(2)

                                                                                                                                                                                                                                                                                                                                      1、管理员登录

                                                                                                                                                                                                                                                                                                                                      • views.py
                                                                                                                                                                                                                                                                                                                                        from django.shortcuts import render, redirect, HttpResponse
                                                                                                                                                                                                                                                                                                                                        from app1.utils.encrypt import md5
                                                                                                                                                                                                                                                                                                                                        from app1 import models
                                                                                                                                                                                                                                                                                                                                        """
                                                                                                                                                                                                                                                                                                                                        登录
                                                                                                                                                                                                                                                                                                                                        """
                                                                                                                                                                                                                                                                                                                                        # 使用form做
                                                                                                                                                                                                                                                                                                                                        from django import forms
                                                                                                                                                                                                                                                                                                                                        from app1.utils.bootstrap import BootStrapForm
                                                                                                                                                                                                                                                                                                                                        class LoginForm(BootStrapForm):  # Form需要自定义字段,
                                                                                                                                                                                                                                                                                                                                            username = forms.CharField(
                                                                                                                                                                                                                                                                                                                                                label="用户名",
                                                                                                                                                                                                                                                                                                                                                widget=forms.PasswordInput(attrs={"class": "form-control"})  # 定义标签
                                                                                                                                                                                                                                                                                                                                            )
                                                                                                                                                                                                                                                                                                                                            password = forms.CharField(
                                                                                                                                                                                                                                                                                                                                                label="密码",
                                                                                                                                                                                                                                                                                                                                                widget=forms.PasswordInput(attrs={"class": "form-control"}, render_value=True)  # 密码标签
                                                                                                                                                                                                                                                                                                                                            )
                                                                                                                                                                                                                                                                                                                                            # 钩子函数,给密码加密,从而可以使数据与后端密码比较
                                                                                                                                                                                                                                                                                                                                            def clean_password(self):
                                                                                                                                                                                                                                                                                                                                                pwd = self.cleaned_data.get("password")
                                                                                                                                                                                                                                                                                                                                                return md5(pwd)
                                                                                                                                                                                                                                                                                                                                        # # ModelForm则是从数据库中拿字段,去数据库拿安全性差些
                                                                                                                                                                                                                                                                                                                                        # class LoginModelForm(forms.ModelForm):
                                                                                                                                                                                                                                                                                                                                        #     class Meta:
                                                                                                                                                                                                                                                                                                                                        #         model = models.VIP
                                                                                                                                                                                                                                                                                                                                        #         fields = ['username', 'password']
                                                                                                                                                                                                                                                                                                                                        def login(request):
                                                                                                                                                                                                                                                                                                                                            if request.method == "GET":
                                                                                                                                                                                                                                                                                                                                                form = LoginForm()
                                                                                                                                                                                                                                                                                                                                                return render(request, 'login.html', {'form': form})
                                                                                                                                                                                                                                                                                                                                            form = LoginForm(data=request.POST)
                                                                                                                                                                                                                                                                                                                                            if form.is_valid():
                                                                                                                                                                                                                                                                                                                                                # form.cleaned_data获取前端用户输入的值(用户名和密码)
                                                                                                                                                                                                                                                                                                                                                # print(form.cleaned_data)  # 验证成功,获取到的用户名和密码,因为form与modelForm不同,form不与数据库关联不可以直接写入数据库
                                                                                                                                                                                                                                                                                                                                                # 去数据库校验用户名和密码是否正确
                                                                                                                                                                                                                                                                                                                                                # 因为上面有个钩子函数,给form.cleaned_data方法加密了,所以这个获取的也是加密的密码
                                                                                                                                                                                                                                                                                                                                                first = models.VIP.objects.filter(**form.cleaned_data).first()
                                                                                                                                                                                                                                                                                                                                                # first = models.VIP.objects.filter(username="xxx", password="xxx").first()  ,如上代替具体见搜索手机号详解,只有字典可以这么用
                                                                                                                                                                                                                                                                                                                                                if not first:
                                                                                                                                                                                                                                                                                                                                                    form.add_error("password", "用户密码错误")  # 给password字段主动添加错误,password从上面18行创建字段表单获取的
                                                                                                                                                                                                                                                                                                                                                    # 存储session到数据库django_session表中自动创建的,也就是用户cookie的凭证,使用cookie的时候得用session来辨别用户
                                                                                                                                                                                                                                                                                                                                                # request.session["info"] = {'id': filter.id, 'username': first.username}  # 获取用户id和username存储到session中,来当用户凭证
                                                                                                                                                                                                                                                                                                                                                request.session["info"] = first.username   # 这里只存储个username
                                                                                                                                                                                                                                                                                                                                                return redirect("/VIP/list/")
                                                                                                                                                                                                                                                                                                                                            return render(request, 'login.html', {'form': form})
                                                                                                                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                                                                                                        • urls.py
                                                                                                                                                                                                                                                                                                                                           # 登录
                                                                                                                                                                                                                                                                                                                                              path('login/', login.login),
                                                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                          • login.html
                                                                                                                                                                                                                                                                                                                                            {% load static %}
                                                                                                                                                                                                                                                                                                                                            
                                                                                                                                                                                                                                                                                                                                            
                                                                                                                                                                                                                                                                                                                                            
                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                Title
                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                            
                                                                                                                                                                                                                                                                                                                                            
                                                                                                                                                                                                                                                                                                                                            

                                                                                                                                                                                                                                                                                                                                            用户登录

                                                                                                                                                                                                                                                                                                                                            {% csrf_token %}
                                                                                                                                                                                                                                                                                                                                            {{ form.username }} {{ form.username.errors.0 }}
                                                                                                                                                                                                                                                                                                                                            {{ form.password }} {{ form.password.errors.0 }}
                                                                                                                                                                                                                                                                                                                                            • cookie和session
                                                                                                                                                                                                                                                                                                                                              request.session["info"] = {'id': filter.id, 'username': first.username}  # 获取用户id和username存储到session中,来当用户凭证
                                                                                                                                                                                                                                                                                                                                                      request.session["info"] = first.username   # 这里只存储个username
                                                                                                                                                                                                                                                                                                                                              

                                                                                                                                                                                                                                                                                                                                              2、校验用户登录

                                                                                                                                                                                                                                                                                                                                              ①校验登录

                                                                                                                                                                                                                                                                                                                                              原理是通过session来获取cookie,如果没有cookie就没有登录过

                                                                                                                                                                                                                                                                                                                                               # 校验是否登录,没登陆跳转登录页面
                                                                                                                                                                                                                                                                                                                                                  info = request.session.get("info")   # 获取session的info字典的用户cookie凭证
                                                                                                                                                                                                                                                                                                                                                  if not info:
                                                                                                                                                                                                                                                                                                                                                      return redirect('/login/')
                                                                                                                                                                                                                                                                                                                                              
                                                                                                                                                                                                                                                                                                                                              ②中间件校验

                                                                                                                                                                                                                                                                                                                                              因为中间键的使用所以,不需要每个views.py中都使用如上代码校验登录。只需要定义一个中间件即可,函数文件中代码不需要改变

                                                                                                                                                                                                                                                                                                                                              • 创建中间件

                                                                                                                                                                                                                                                                                                                                                在app1下创建个文件夹middleware,再创建个auth.py。里面代码如下

                                                                                                                                                                                                                                                                                                                                                from django.utils.deprecation import MiddlewareMixin
                                                                                                                                                                                                                                                                                                                                                from django.shortcuts import HttpResponse,redirect
                                                                                                                                                                                                                                                                                                                                                # 中间件校验用户是否登录
                                                                                                                                                                                                                                                                                                                                                class AuthMiddleware(MiddlewareMixin):
                                                                                                                                                                                                                                                                                                                                                    """中间件1"""
                                                                                                                                                                                                                                                                                                                                                    def process_request(self, request):
                                                                                                                                                                                                                                                                                                                                                        # 排除那些不需要登录校验的页面
                                                                                                                                                                                                                                                                                                                                                        if request.path_info == "/login/":
                                                                                                                                                                                                                                                                                                                                                            return
                                                                                                                                                                                                                                                                                                                                                        # 读取当前访问的用户session信息,如若读到证明登录过,则继续执行
                                                                                                                                                                                                                                                                                                                                                        info_dict = request.session.get("info")
                                                                                                                                                                                                                                                                                                                                                        if info_dict:
                                                                                                                                                                                                                                                                                                                                                            return
                                                                                                                                                                                                                                                                                                                                                        # 没有登录信息
                                                                                                                                                                                                                                                                                                                                                        return redirect('/login/')
                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                • 注册中间件

                                                                                                                                                                                                                                                                                                                                                  setting.py文件中,每个类是一个中间件

                                                                                                                                                                                                                                                                                                                                                  Django银角大王武沛齐配套视频笔记,python全栈开发、pythonWeb,image-20221112112435796,第46张

                                                                                                                                                                                                                                                                                                                                                  3、注销

                                                                                                                                                                                                                                                                                                                                                  • 原理

                                                                                                                                                                                                                                                                                                                                                    删除cookie即可,因为没有cookie需要重新登录

                                                                                                                                                                                                                                                                                                                                                    • login.py
                                                                                                                                                                                                                                                                                                                                                      def logout(request):
                                                                                                                                                                                                                                                                                                                                                          request.session.clear()  # 将当前用户的session删除掉,等于将用户cookie删除
                                                                                                                                                                                                                                                                                                                                                          return redirect('/login/')
                                                                                                                                                                                                                                                                                                                                                      
                                                                                                                                                                                                                                                                                                                                                      • urls.py
                                                                                                                                                                                                                                                                                                                                                         # 注销
                                                                                                                                                                                                                                                                                                                                                            path('logout/', login.logout),
                                                                                                                                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                                                                                                                        • layout.html

                                                                                                                                                                                                                                                                                                                                                          将html的注销标签的执行函数地址改一下

                                                                                                                                                                                                                                                                                                                                                        • 注销
                                                                                                                                                                                                                                                                                                                                                        • 4、显示当前用户名

                                                                                                                                                                                                                                                                                                                                                          随着用户改变用户名也会跟着自动改变

                                                                                                                                                                                                                                                                                                                                                          • 获取当前用户的账号和密码
                                                                                                                                                                                                                                                                                                                                                            # 通过session来获取当前用户的账号和密码
                                                                                                                                                                                                                                                                                                                                                                info = request.session.get("info")   # 获取session的info字典的用户cookie凭证
                                                                                                                                                                                                                                                                                                                                                                # 取值,存储在session中用户输入的账号和密码
                                                                                                                                                                                                                                                                                                                                                                info["id"]   
                                                                                                                                                                                                                                                                                                                                                                info["username"]
                                                                                                                                                                                                                                                                                                                                                            
                                                                                                                                                                                                                                                                                                                                                            • 应用在前端
                                                                                                                                                                                                                                                                                                                                                              {{ request.session.info.username }}
                                                                                                                                                                                                                                                                                                                                                              
                                                                                                                                                                                                                                                                                                                                                              • 效果:

                                                                                                                                                                                                                                                                                                                                                                Django银角大王武沛齐配套视频笔记,python全栈开发、pythonWeb,image-20221112115837199,第47张

                                                                                                                                                                                                                                                                                                                                                                • 获取的是login.py文件夹存储入session的值:

                                                                                                                                                                                                                                                                                                                                                                  Django银角大王武沛齐配套视频笔记,python全栈开发、pythonWeb,image-20221112115758287,第48张

                                                                                                                                                                                                                                                                                                                                                                  5、图片验证码

                                                                                                                                                                                                                                                                                                                                                                  ①pillow插件

                                                                                                                                                                                                                                                                                                                                                                  自动生成验证码图片插件

                                                                                                                                                                                                                                                                                                                                                                  Ⅰ、安装插件
                                                                                                                                                                                                                                                                                                                                                                  pip install pillow
                                                                                                                                                                                                                                                                                                                                                                  

                                                                                                                                                                                                                                                                                                                                                                  或者到pycham设置中项目-python解释器中安装

                                                                                                                                                                                                                                                                                                                                                                  Ⅱ、使用

                                                                                                                                                                                                                                                                                                                                                                  参考文献:https://www.cnblogs.com/wupeiqi/articles/5812291.html

                                                                                                                                                                                                                                                                                                                                                                  Ⅲ、字体文件

                                                                                                                                                                                                                                                                                                                                                                  生成验证码的字体:

                                                                                                                                                                                                                                                                                                                                                                  Ⅳ、验证码的生成与校验
                                                                                                                                                                                                                                                                                                                                                                  • code.py

                                                                                                                                                                                                                                                                                                                                                                    自定义的工具包文件,注意修改第4行的字体路径,这个字体是和app1在同一个目录下

                                                                                                                                                                                                                                                                                                                                                                    import random
                                                                                                                                                                                                                                                                                                                                                                    from PIL import Image, ImageDraw, ImageFont, ImageFilter
                                                                                                                                                                                                                                                                                                                                                                    def check_code(width=120, height=30, char_length=5, font_file='Monaco.ttf', font_size=28):
                                                                                                                                                                                                                                                                                                                                                                        code = []
                                                                                                                                                                                                                                                                                                                                                                        img = Image.new(mode='RGB', size=(width, height), color=(255, 255, 255))
                                                                                                                                                                                                                                                                                                                                                                        draw = ImageDraw.Draw(img, mode='RGB')
                                                                                                                                                                                                                                                                                                                                                                        def rndChar():
                                                                                                                                                                                                                                                                                                                                                                            """
                                                                                                                                                                                                                                                                                                                                                                            生成随机字母
                                                                                                                                                                                                                                                                                                                                                                            :return:
                                                                                                                                                                                                                                                                                                                                                                            """
                                                                                                                                                                                                                                                                                                                                                                            # return str(random.randint(0, 9))  # 生成数字
                                                                                                                                                                                                                                                                                                                                                                            return chr(random.randint(65, 90))  # 生成字母
                                                                                                                                                                                                                                                                                                                                                                        def rndColor():
                                                                                                                                                                                                                                                                                                                                                                            """
                                                                                                                                                                                                                                                                                                                                                                            生成随机颜色
                                                                                                                                                                                                                                                                                                                                                                            :return:
                                                                                                                                                                                                                                                                                                                                                                            """
                                                                                                                                                                                                                                                                                                                                                                            return random.randint(0, 255), random.randint(10, 255), random.randint(64, 255)
                                                                                                                                                                                                                                                                                                                                                                        # 写文字
                                                                                                                                                                                                                                                                                                                                                                        font = ImageFont.truetype(font_file, font_size)
                                                                                                                                                                                                                                                                                                                                                                        for i in range(char_length):
                                                                                                                                                                                                                                                                                                                                                                            char = rndChar()
                                                                                                                                                                                                                                                                                                                                                                            code.append(char)
                                                                                                                                                                                                                                                                                                                                                                            h = random.randint(0, 4)
                                                                                                                                                                                                                                                                                                                                                                            draw.text([i * width / char_length, h], char, font=font, fill=rndColor())
                                                                                                                                                                                                                                                                                                                                                                        # 写干扰点
                                                                                                                                                                                                                                                                                                                                                                        for i in range(40):
                                                                                                                                                                                                                                                                                                                                                                            draw.point([random.randint(0, width), random.randint(0, height)], fill=rndColor())
                                                                                                                                                                                                                                                                                                                                                                        # 写干扰圆圈
                                                                                                                                                                                                                                                                                                                                                                        for i in range(40):
                                                                                                                                                                                                                                                                                                                                                                            draw.point([random.randint(0, width), random.randint(0, height)], fill=rndColor())
                                                                                                                                                                                                                                                                                                                                                                            x = random.randint(0, width)
                                                                                                                                                                                                                                                                                                                                                                            y = random.randint(0, height)
                                                                                                                                                                                                                                                                                                                                                                            draw.arc((x, y, x + 4, y + 4), 0, 90, fill=rndColor())
                                                                                                                                                                                                                                                                                                                                                                        # 画干扰线
                                                                                                                                                                                                                                                                                                                                                                        for i in range(5):
                                                                                                                                                                                                                                                                                                                                                                            x1 = random.randint(0, width)
                                                                                                                                                                                                                                                                                                                                                                            y1 = random.randint(0, height)
                                                                                                                                                                                                                                                                                                                                                                            x2 = random.randint(0, width)
                                                                                                                                                                                                                                                                                                                                                                            y2 = random.randint(0, height)
                                                                                                                                                                                                                                                                                                                                                                            draw.line((x1, y1, x2, y2), fill=rndColor())
                                                                                                                                                                                                                                                                                                                                                                        img = img.filter(ImageFilter.EDGE_ENHANCE_MORE)
                                                                                                                                                                                                                                                                                                                                                                        return img, ''.join(code)
                                                                                                                                                                                                                                                                                                                                                                    
                                                                                                                                                                                                                                                                                                                                                                    • login.html
                                                                                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                                                      {# #} {# #} {{ form.code }} {{ form.code.errors.0 }}
                                                                                                                                                                                                                                                                                                                                                                      Django银角大王武沛齐配套视频笔记,python全栈开发、pythonWeb,第49张
                                                                                                                                                                                                                                                                                                                                                                      • auth.py中间件

                                                                                                                                                                                                                                                                                                                                                                        Django银角大王武沛齐配套视频笔记,python全栈开发、pythonWeb,image-20221112160826070,第50张

                                                                                                                                                                                                                                                                                                                                                                      • login.py

                                                                                                                                                                                                                                                                                                                                                                        核心代码53-58

                                                                                                                                                                                                                                                                                                                                                                        from django.shortcuts import render, redirect, HttpResponse
                                                                                                                                                                                                                                                                                                                                                                        from app1.utils.encrypt import md5
                                                                                                                                                                                                                                                                                                                                                                        from app1 import models
                                                                                                                                                                                                                                                                                                                                                                        from app1.utils.code import check_code
                                                                                                                                                                                                                                                                                                                                                                        from io import BytesIO
                                                                                                                                                                                                                                                                                                                                                                        # 使用form做
                                                                                                                                                                                                                                                                                                                                                                        from django import forms
                                                                                                                                                                                                                                                                                                                                                                        from app1.utils.bootstrap import BootStrapForm
                                                                                                                                                                                                                                                                                                                                                                        class LoginForm(BootStrapForm):  # Form需要自定义字段,
                                                                                                                                                                                                                                                                                                                                                                            username = forms.CharField(
                                                                                                                                                                                                                                                                                                                                                                                label="用户名",
                                                                                                                                                                                                                                                                                                                                                                                widget=forms.TextInput(attrs={"class": "form-control"})  # 定义标签
                                                                                                                                                                                                                                                                                                                                                                            )
                                                                                                                                                                                                                                                                                                                                                                            password = forms.CharField(
                                                                                                                                                                                                                                                                                                                                                                                label="密码",
                                                                                                                                                                                                                                                                                                                                                                                widget=forms.PasswordInput(attrs={"class": "form-control"}, render_value=True)  # 密码标签
                                                                                                                                                                                                                                                                                                                                                                            )
                                                                                                                                                                                                                                                                                                                                                                            code = forms.CharField(
                                                                                                                                                                                                                                                                                                                                                                                label="验证码",
                                                                                                                                                                                                                                                                                                                                                                                widget=forms.TextInput,
                                                                                                                                                                                                                                                                                                                                                                                required=True
                                                                                                                                                                                                                                                                                                                                                                            )
                                                                                                                                                                                                                                                                                                                                                                            # 钩子函数,给密码加密,从而可以使数据与后端密码比较
                                                                                                                                                                                                                                                                                                                                                                            def clean_password(self):
                                                                                                                                                                                                                                                                                                                                                                                pwd = self.cleaned_data.get("password")
                                                                                                                                                                                                                                                                                                                                                                                return md5(pwd)
                                                                                                                                                                                                                                                                                                                                                                        # # ModelForm则是从数据库中拿字段,去数据库拿安全性差些
                                                                                                                                                                                                                                                                                                                                                                        # class LoginModelForm(forms.ModelForm):
                                                                                                                                                                                                                                                                                                                                                                        #     class Meta:
                                                                                                                                                                                                                                                                                                                                                                        #         model = models.VIP
                                                                                                                                                                                                                                                                                                                                                                        #         fields = ['username', 'password']
                                                                                                                                                                                                                                                                                                                                                                        """
                                                                                                                                                                                                                                                                                                                                                                        登录
                                                                                                                                                                                                                                                                                                                                                                        """
                                                                                                                                                                                                                                                                                                                                                                        def login(request):
                                                                                                                                                                                                                                                                                                                                                                            if request.method == "GET":
                                                                                                                                                                                                                                                                                                                                                                                form = LoginForm()
                                                                                                                                                                                                                                                                                                                                                                                return render(request, 'login.html', {'form': form})
                                                                                                                                                                                                                                                                                                                                                                            form = LoginForm(data=request.POST)
                                                                                                                                                                                                                                                                                                                                                                            if form.is_valid():
                                                                                                                                                                                                                                                                                                                                                                                # form.cleaned_data获取前端用户输入的值(用户名和密码、验证码)
                                                                                                                                                                                                                                                                                                                                                                                # print(form.cleaned_data)  # 验证成功,获取到的用户名和密码,因为form与modelForm不同,form不与数据库关联不可以直接写入数据库
                                                                                                                                                                                                                                                                                                                                                                                # 验证码校验,并使用pop()把code验证码的值剔除掉,从而保证其不会被存储入数据库
                                                                                                                                                                                                                                                                                                                                                                                user_input_code = form.cleaned_data['code']  # 用户填写的验证码
                                                                                                                                                                                                                                                                                                                                                                                code = request.session.get('image_code', "")
                                                                                                                                                                                                                                                                                                                                                                                if code == user_input_code:
                                                                                                                                                                                                                                                                                                                                                                                    form.add_error("code", "验证码错误")
                                                                                                                                                                                                                                                                                                                                                                                    return render(request, 'login.html', {'form': form})
                                                                                                                                                                                                                                                                                                                                                                                # 去数据库校验用户名和密码是否正确
                                                                                                                                                                                                                                                                                                                                                                                # 因为上面有个钩子函数,给form.cleaned_data方法加密了,所以这个获取的也是加密的密码
                                                                                                                                                                                                                                                                                                                                                                                first = models.VIP.objects.filter(**form.cleaned_data).first()
                                                                                                                                                                                                                                                                                                                                                                                # first = models.VIP.objects.filter(username="xxx", password="xxx").first()  ,如上代替具体见搜索手机号详解,只有字典可以这么用
                                                                                                                                                                                                                                                                                                                                                                                if not first:
                                                                                                                                                                                                                                                                                                                                                                                    form.add_error("password", "用户密码错误")  # 给password字段主动添加错误,password从上面18行创建字段表单获取的
                                                                                                                                                                                                                                                                                                                                                                                    # 存储session到数据库django_session表中自动创建的,也就是用户cookie的凭证,使用cookie的时候得用session来辨别用户
                                                                                                                                                                                                                                                                                                                                                                                request.session["info"] = {'username': first.username}  # 获取用户id和username存储到session中,来当用户凭证,这里只存储username
                                                                                                                                                                                                                                                                                                                                                                                # 设置session存活时间,7天内免登录
                                                                                                                                                                                                                                                                                                                                                                                request.session.set_expiry(60 * 60 * 24 * 7)
                                                                                                                                                                                                                                                                                                                                                                                return redirect("/VIP/list/")
                                                                                                                                                                                                                                                                                                                                                                            return render(request, 'login.html', {'form': form})
                                                                                                                                                                                                                                                                                                                                                                        """
                                                                                                                                                                                                                                                                                                                                                                        验证码
                                                                                                                                                                                                                                                                                                                                                                        """
                                                                                                                                                                                                                                                                                                                                                                        def image(request):
                                                                                                                                                                                                                                                                                                                                                                            # 调用pillow函数,生成图片
                                                                                                                                                                                                                                                                                                                                                                            img, code_string = check_code()
                                                                                                                                                                                                                                                                                                                                                                            # 将生成的验证码写入session中,方便后续用于校验
                                                                                                                                                                                                                                                                                                                                                                            request.session['image_code'] = code_string
                                                                                                                                                                                                                                                                                                                                                                            # 给Session设置60秒超时,即验证码有效时间只有60s
                                                                                                                                                                                                                                                                                                                                                                            request.session.set_expiry(60)
                                                                                                                                                                                                                                                                                                                                                                            stream = BytesIO()  # 在内存中创建一个文件
                                                                                                                                                                                                                                                                                                                                                                            img.save(stream, 'png')  # 将生成的img文件写入,文件中
                                                                                                                                                                                                                                                                                                                                                                            return HttpResponse(stream.getvalue())
                                                                                                                                                                                                                                                                                                                                                                        

                                                                                                                                                                                                                                                                                                                                                                        九、Ajax异步请求

                                                                                                                                                                                                                                                                                                                                                                        发送局部请求

                                                                                                                                                                                                                                                                                                                                                                        1、ajax发送get请求

                                                                                                                                                                                                                                                                                                                                                                        • 前端页面
                                                                                                                                                                                                                                                                                                                                                                          {% extends 'layout.html' %}
                                                                                                                                                                                                                                                                                                                                                                          {% block content %}
                                                                                                                                                                                                                                                                                                                                                                              

                                                                                                                                                                                                                                                                                                                                                                          任务管理

                                                                                                                                                                                                                                                                                                                                                                          示例1

                                                                                                                                                                                                                                                                                                                                                                          {% endblock %} {% block js %} {% endblock %} $.ajax({ url: '/task/ajax/', // 发送的地址 type: "get", data: { n1: 123, n2: 456 }, success: function (res) { console.log(res); } }) {% endblock %}
                                                                                                                                                                                                                                                                                                                                                                          • 后端接收请求
                                                                                                                                                                                                                                                                                                                                                                            from django.shortcuts import render, HttpResponse
                                                                                                                                                                                                                                                                                                                                                                            def task_ajax(request):
                                                                                                                                                                                                                                                                                                                                                                                print(request.GET)
                                                                                                                                                                                                                                                                                                                                                                                return HttpResponse("成功了")
                                                                                                                                                                                                                                                                                                                                                                            
                                                                                                                                                                                                                                                                                                                                                                            • urls.py
                                                                                                                                                                                                                                                                                                                                                                               # ajax请求
                                                                                                                                                                                                                                                                                                                                                                                  path('ajax/task/', ajax.task_ajax)
                                                                                                                                                                                                                                                                                                                                                                              

                                                                                                                                                                                                                                                                                                                                                                              2、ajax发送post请求

                                                                                                                                                                                                                                                                                                                                                                              • 前端页面
                                                                                                                                                                                                                                                                                                                                                                                {% extends 'layout.html' %}
                                                                                                                                                                                                                                                                                                                                                                                {% block content %}
                                                                                                                                                                                                                                                                                                                                                                                    

                                                                                                                                                                                                                                                                                                                                                                                任务管理

                                                                                                                                                                                                                                                                                                                                                                                示例1

                                                                                                                                                                                                                                                                                                                                                                                {% endblock %} {% block js %} {% endblock %}
                                                                                                                                                                                                                                                                                                                                                                                • 后端
                                                                                                                                                                                                                                                                                                                                                                                  from django.shortcuts import render, HttpResponse
                                                                                                                                                                                                                                                                                                                                                                                  from django.views.decorators.csrf import csrf_exempt
                                                                                                                                                                                                                                                                                                                                                                                  @csrf_exempt
                                                                                                                                                                                                                                                                                                                                                                                  def task_ajax(request):
                                                                                                                                                                                                                                                                                                                                                                                      print(request.GET)
                                                                                                                                                                                                                                                                                                                                                                                      print(request.POST)
                                                                                                                                                                                                                                                                                                                                                                                      return HttpResponse("成功了")
                                                                                                                                                                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                                                                                                                                                  • urls.py
                                                                                                                                                                                                                                                                                                                                                                                     # ajax请求
                                                                                                                                                                                                                                                                                                                                                                                        path('ajax/task/', ajax.task_ajax)
                                                                                                                                                                                                                                                                                                                                                                                    

                                                                                                                                                                                                                                                                                                                                                                                    3、绑定事件

                                                                                                                                                                                                                                                                                                                                                                                    • 前端
                                                                                                                                                                                                                                                                                                                                                                                      {% extends 'layout.html' %}
                                                                                                                                                                                                                                                                                                                                                                                      {% block content %}
                                                                                                                                                                                                                                                                                                                                                                                          

                                                                                                                                                                                                                                                                                                                                                                                      任务管理

                                                                                                                                                                                                                                                                                                                                                                                      示例1

                                                                                                                                                                                                                                                                                                                                                                                      {% endblock %} {% block js %} {% endblock %}

                                                                                                                                                                                                                                                                                                                                                                                      4、ajax的返回值

                                                                                                                                                                                                                                                                                                                                                                                      返回值是json格式

                                                                                                                                                                                                                                                                                                                                                                                      {% extends 'layout.html' %}
                                                                                                                                                                                                                                                                                                                                                                                      {% block content %}
                                                                                                                                                                                                                                                                                                                                                                                          

                                                                                                                                                                                                                                                                                                                                                                                      任务管理

                                                                                                                                                                                                                                                                                                                                                                                      示例1

                                                                                                                                                                                                                                                                                                                                                                                      {% endblock %} {% block js %} {% endblock %}
                                                                                                                                                                                                                                                                                                                                                                                      • 后端
                                                                                                                                                                                                                                                                                                                                                                                        from django.shortcuts import render, redirect, HttpResponse
                                                                                                                                                                                                                                                                                                                                                                                        from django.views.decorators.csrf import csrf_exempt
                                                                                                                                                                                                                                                                                                                                                                                        import json
                                                                                                                                                                                                                                                                                                                                                                                        from django.http import JsonResponse
                                                                                                                                                                                                                                                                                                                                                                                        def task_list(request):
                                                                                                                                                                                                                                                                                                                                                                                            """ 任务列表 """
                                                                                                                                                                                                                                                                                                                                                                                            return render(request, "task_list.html")
                                                                                                                                                                                                                                                                                                                                                                                        @csrf_exempt
                                                                                                                                                                                                                                                                                                                                                                                        def task_ajax(request):
                                                                                                                                                                                                                                                                                                                                                                                            print(request.GET)
                                                                                                                                                                                                                                                                                                                                                                                            print(request.POST)
                                                                                                                                                                                                                                                                                                                                                                                            data_dict = {"status": True, 'data': [11, 22, 33, 44]}
                                                                                                                                                                                                                                                                                                                                                                                            return HttpResponse(json.dumps(data_dict))  # 将数据返回去前端页面
                                                                                                                                                                                                                                                                                                                                                                                            # return JsonResponse(data_dict)  # django带的方法可以简化如上返回代码,需要导包
                                                                                                                                                                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                                                                                                                                                        • urls.py
                                                                                                                                                                                                                                                                                                                                                                                           # ajax请求
                                                                                                                                                                                                                                                                                                                                                                                              path('ajax/task/', ajax.task_ajax)
                                                                                                                                                                                                                                                                                                                                                                                          

                                                                                                                                                                                                                                                                                                                                                                                          5、测试代码

                                                                                                                                                                                                                                                                                                                                                                                          • task.html
                                                                                                                                                                                                                                                                                                                                                                                            {% extends 'layout.html' %}
                                                                                                                                                                                                                                                                                                                                                                                            {% block content %}
                                                                                                                                                                                                                                                                                                                                                                                                    

                                                                                                                                                                                                                                                                                                                                                                                            Ajax学习

                                                                                                                                                                                                                                                                                                                                                                                            示例2

                                                                                                                                                                                                                                                                                                                                                                                            示例3

{% endblock %} {% block js %} {% endblock %}
  • ajax.py
    from django.shortcuts import render, redirect, HttpResponse
    from django.views.decorators.csrf import csrf_exempt
    import json
    from django.http import JsonResponse
    def task_list(request):
        """ 任务列表 """
        return render(request, "task_list.html")
    @csrf_exempt
    def task_ajax(request):
        print(request.GET)
        print(request.POST)
        data_dict = {"status": True, 'data': [11, 22, 33, 44]}
        return HttpResponse(json.dumps(data_dict))  # 将数据返回去前端页面
        # return JsonResponse(data_dict)  # django带的方法可以简化如上返回代码,需要导包
    
    • urls.py
      # ajax请求,注意导入ajax.py包,views文件夹中
          path('ajax/task/', ajax.task_ajax),
          path('ajax/list/', ajax.task_list),
      

      十、回顾与梳理

      知识点的回顾:

      • 安装Djangox

        pip install django
        
      • 创建Django项目

        >>> django-admin startproject mysite
        

        注意:Pycharm可以创建。如果用Pycharm创建,记得settings.py中的DIR templates 删除。

      • 创建app & 注册

        >>>python manage.py startapp app01
        >>>python manage.py startapp app02
        >>>python manage.py startapp app03
        
        INSTALLED_APPS = [
            ...
            'app01.apps.App01Config'
        ]
        

        注意:否则app下的models.py写类时,无法在数据库中创建表。

      • 配置 静态文件路径 & 模板的路径(放在app目录下)。

        • static、templates、utils
        • 配置数据库相关操作(MySQL)

          • 第三方模块(django3版本)

            pip install mysqlclient
            
          • 自己先去MySQL创建一个数据库。

            mysql -u root -p
            CREATE DATABASE djangodemo3 CHARACTER SET utf8 COLLATE utf8_general_ci;  utf-8后面是排列规则
            
          • 配置数据库连接settings.py

            DATABASES = {
                'default': {
                    'ENGINE': 'django.db.backends.mysql',
                    'NAME': 'djangoDemo3',  # 数据库名字
                    'USER': 'root',
                    'PASSWORD': '1234',
                    'HOST': '127.0.0.1',  # 哪台机器安装了MySQL
                    'PORT': 3306,
                }
            }
            
          • 在app下的models.py中编写

            from django.db import models
            class Admin(models.Model):
                """ 管理员 """
                username = models.CharField(verbose_name="用户名", max_length=32)
                password = models.CharField(verbose_name="密码", max_length=64)
                def __str__(self):
                    return self.username
                
            class Department(models.Model):
                """ 部门表 """
                title = models.CharField(verbose_name='标题', max_length=32)
                def __str__(self):
                    return self.title
            
          • 执行两个命令:

            >>>python manange.py makemigrations
            >>>python manange.py migrate
            
          • 在 urls.py ,路由 ( URL 和 函数的对应关系)。

          • 在views.py,视图函数,编写业务逻辑。

          • templates目录,编写HTML模板(含有模板语法、继承、{% static 'xx'%})

          • ModelForm & Form组件,在我们开发增删改查功能。

            • 生成HTML标签(生成默认值)
            • 请求数据进行校验。
            • 保存到数据库(ModelForm)
            • 获取错误信息。
            • Cookie和Session,用户登录信息保存起来。

            • 中间件,基于中间件实现用户认证 ,基于:process_request。

            • ORM操作

              models.User.objects.filter(id="xxx")
              models.User.objects.filter(id="xxx").order_by("-id")
              
            • 分页组件。