最新要闻

广告

手机

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

家电

全球快资讯:框架第三课---作业讲解(数据增删改查),django请求生命周期流程图,django路由层,反向解析

来源:博客园

上周内容回顾

  • 静态文件及相关配置


    (资料图片仅供参考)

    1.静态文件的概念简单的理解为html页面需要使用到的不经常变化的资源    css文件、js文件、img文件、第三方文件2.访问静态文件配置STATIC_URLS = "/static/"STATICFILES_DIRS = [        os.path.join(BASE_DIR,"static")    ]3.接口前缀动态匹配{% load static %}{% static "bbb/ccc/d.txt" %}
  • form表单相关注意事项

    form标签重要属性action控制数据提交的地址!!!  三种编写方式:  什么都不写默认朝当前form表单所在页面提交  写全路径,写什么路径就朝什么路径提交  写一个路由,朝当前服务端对应的路由地址提交!!method控制提交的方法    两种方法 默认是get网络请求方式get 朝服务端请求数据并且可以携带一些额外的不敏感的条件(大小有限制2kb左右)            URL?xxx=yyy&ooo=ppppost    朝服务端提交数据       也可以携带数据并且数据是放在请求体里面的(大小没有限制)            请求体
  • request对象方法

    request.method获取当前请求的请求方法 结果是纯大写的字符串 GET、POST

request.GET获取URL问号后面携带的数据结果是一个QueryDict拥有字典的特性request.GET.get()值列表最后一个数据值request.GET.getlist()整个值列表

request.POST获取post请求请求体里面的数据结果也是一个QueryDict拥有字典的特性request.POST.get()值列表最后一个数据值request.POST.getlist()整个值列表

* pycharm连接数据库```python1.database选项2.对应的数据库驱动
  • django连接数据库

    1.django默认自带sqlite3小型数据库2.我们可以指定其他数据库 比如MySQL3.配置文件中需要修改配置 DATABASESDATABASES = {  # "default": {  #     "ENGINE": "django.db.backends.sqlite3",  #     "NAME": os.path.join(BASE_DIR, "db.sqlite3"),  # }  "default": {      "ENGINE": "django.db.backends.mysql",      "NAME": "day51",      "HOST": "127.0.0.1",      "PORT": "3306",      "USER": "root",      "PASSWORD": "222",      "CHARSET": "utf8",  }

}1.添加相关配置mysql、NAME、HOST、PORT、USER、PASSWORD、CHARSET2.需要下载mysqlclient模块(如果是django1.X版本可以用pymysql)

* orm简介对象关系映射(Object Relational Mapping)```python对象关系映射1.优势简单方便快捷2.劣势效率可能会低
  • 数据库迁移命令

    1.models.py中编写了与数据库相关的代码2.将代码操作记录下来 migrations目录python38 manage.py makemigrations3.将操作真正同步到数据库中python38 manage.py migrate"""首次创建django会额外创建很多内部需要用到的表 针对程序员自己创建的表名在表名前面加上应用前缀用于区分多个应用表名可能冲突的情况"""
  • orm基本操作

    models.UserInfo.objects.create()  # insert intomodels.UserInfo.objects.filter()  # wheremodels.UserInfo.objects.filter().update()  # updatemodels.UserInfo.objects.filter().delete()  # delete from

models.表名.objects.creat()models.表名.objects.filter()models.表名.objects.filter().update()models.表名.objects.filter().delete()

今日内容概要

  • 作业讲解(数据增删改查)
  • django请求生命周期流程图
  • django路由层
  • python虚拟环境(跳过)
  • 反向解析
  • 路由分发
  • 名称空间

今日内容详细

准备工作

先pycharm连接数据库

settings里面注掉一行代码!!!防止post请求报错!!MIDDLEWARE = [# "django.middleware.csrf.CsrfViewMiddleware",]TEMPLATES里面路径重新写一下"DIRS": [os.path.join(BASE_DIR, "templates")]

django连接数据库 settings里面也要配置一下,如果是用的django自带的数据库可以不用改DATABASES = {# "default": {# "ENGINE": "django.db.backends.sqlite3",# "NAME": os.path.join(BASE_DIR, "db.sqlite3"),"default": {"ENGINE": "django.db.backends.mysql","NAME": "day51", # 写你要操作的库名"HOST": "127.0.0.1","PORT": "3306","USER": "root","PASSWORD": "222","CHARSET": "utf8",}}

可视化界面之数据增删改查

针对数据对象主键字段的获取可以使用更加方便的 obj.pk获取在模型类中定义双下str方法可以在数据对象被执行打印操作的时候方便的查看"""{# 前端需要获取数据,并且发送给后端,目前只有form表单能实现!!#}form表单中能够触发调剂动作的按钮只有两个"""1.数据展示功能开设接口、获取数据、传递页面、展示数据获取user表里面所有的数据!!利用模板语法传递数据到html页面并完成处理,最终返回浏览器展示!!----------------------------------------------------------------------------------------------------2.数据添加功能开设接口、获取数据、发送数据、校验数据、录入数据、重定向先返回一个获取新增用户数据的html页面根据不同的请求方式做不同的处理获取用户相关数据一些小判断(不如用户名密码不能为空,)筛选用户名是否已存在!如果用户名也没用重复就可以往数据库添加了一条数据了!!数据添加完了后,重定向到数据展示页!!!----------------------------------------------------------------------------------------------------3.数据编辑功能开设接口、后端如何区分所要编辑的数据(问号携带参数)、后端获取用户数据、前端展示默认数据、获取用户并完成更新-------{# a标签的href=网址 点击a标签就会跳转到该网址去!就是朝该网址发了一个get请求!!!#}get请求有想加点东西,在路由的后面通过问号?的方式携带一些数据!!-------编辑页展示出来的时候,需要在后端提前将拿到的用户数据,然后给两个input框加默认值,这样就展示出来的时候input框里面就有用户想要改的数据了!!!这样用户就比较方便了!!!给input框添加value属性性!!!--------获取用户想要编辑的数据主键值根据主键值去数据库查找筛选获取对应的数据根据拿到的数据返回一个编辑数据的页面,并且该页面上需要提前展示出原来的数据!!根据不同的请求处理不同逻辑,先对获取的前端post请求信息来点小判断!!用户在编辑页面编辑的信息提交后,经过判断后确定没问题后,开始更新数据库里面对应的信息数据更新完了后,重定向到数据展示页!!!----------------------------------------------------------------------------------------------------4.数据删除功能开设接口、问号携带参数、删除二次确认获取用户想要编辑的数据主键值在html页面利用对删除按钮的点击事件触发确认框,并根据返回值,确认用户到底想不想删,如果不想删,利用jQuery事件的return false取消掉a标签自身的点击跳转到删除视图函数的功能,这样就删不成数据了!!!根据主键值去数据库查找筛选获取对应的数据数据更新完了后,重定向到数据展示页!----------------------------------------------------------------------------------------------------

.

整体全部的代码!!!

views.py 文件代码

from django.shortcuts import render, HttpResponse, redirectfrom app01 import models# Create your views here.def user_list_func(request):    # 1.获取user表里面所有的数据展示到html页面上!!    user_data = models.Users.objects.filter()  # 查所有数据 列表套字典或者说列表套对象 Queryset [对象1,对象2,]    # 2. 利用模板语法传递数据到html页面并完成处理,最终返回浏览器展示    return render(request, "userList_page.html", {"user_data": user_data})    # 返回html页面,并将列表也传给html页面!!!----------------------------------------------------------------------------------------------------def user_add_func(request):    # 2.根据不同的请求方式做不同的处理    if request.method == "POST":        # 3.获取用户相关数据        username = request.POST.get("username")  # 拿前端post请求提交的数据        user_age = request.POST.get("age")        # 4.一些小判断(不如用户名密码不能为空,)        if len(username) == 0 or len(user_age) == 0:            return HttpResponse("用户名年龄不能为空!")        # 5.筛选用户名是否已存在!        res = models.Users.objects.filter(name=username)        if res:            return HttpResponse("用户名已存在!")        # 6. 如果用户名也没用重复就可以往数据库添加了一条数据了!!        models.Users.objects.create(name=username, age=user_age)        # 7. 数据添加完了后,重定向到数据展示页!!!        return redirect("/user_list/")    # return HttpResponse("添加用户数据")    # 1. 先返回一个获取新增用户数据的html页面    return render(request, "userAdd_page.html")----------------------------------------------------------------------------------------------------def user_edit_func(request):    # return HttpResponse("用户数据编辑")    # 1.获取用户想要编辑的数据主键值    target_edit_id = request.GET.get("edit_id")    # 4. 根据不同的请求处理不同逻辑    if request.method == "POST":        username = request.POST.get("username")  # 拿前端post请求提交的数据        user_age = request.POST.get("age")        if len(username) == 0 or len(user_age) == 0:            return HttpResponse("用户名年龄不能为空!")        # 5. 用户在编辑页面编辑的信息提交后,经过判断后确定没问题后,开始更新数据库里面对应的信息        models.Users.objects.filter(pk=target_edit_id).update(name=username, age=user_age)        # 6. 数据更新完了后,重定向到数据展示页!!!        return redirect("/user_list/")    # 2.根据主键值去数据库查找筛选获取对应的数据    target_edit_obj = models.Users.objects.filter(pk=target_edit_id)[0]  # 注意filter拿到的是Queryset是列表套对象所以要索引0才能拿到对象    # 3.根据拿到的数据返回一个编辑数据的页面,并且该页面上需要提前展示出原来的数据!!    return render(request, "userEdit_page.html", {"target_edit_obj": target_edit_obj})----------------------------------------------------------------------------------------------------def user_delete_func(request):    # return HttpResponse("删除数据")    # 1.获取用户想要编辑的数据主键值    target_edit_id = request.GET.get("delete_id")    # 2.根据主键值去数据库查找筛选获取对应的数据,然后删除    target_edit_obj = models.Users.objects.filter(pk=target_edit_id).delete()    # 3.数据更新完了后,重定向到数据展示页!!!    return redirect("/user_list/")

.

urls.py 文件代码

from django.contrib import adminfrom django.urls import pathfrom app01 import viewsurlpatterns = [    path("admin/", admin.site.urls),    # 访问用户数据的接口    path("user_list/", views.user_list_func),    # 添加用户数据的接口    path("user_add/", views.user_add_func),    # 编辑用户数据的接口    path("user_edit/", views.user_edit_func),    # 删除用户数据的接口    path("user_delete/", views.user_delete_func),]

.

models.py 文件代码

from django.db import models# Create your models here.class Users(models.Model):    id = models.AutoField(primary_key=True)    name = models.CharField(max_length=32)    age = models.IntegerField()    def __str__(self):        return "用户对象:%s"% self.name# 此处写个魔法方法,当我们打印对象的时候会触发它执行,作用就是能让我在打印对象的时候看下对象的内容,# 就是为了便于对象打印之后查看,不影响数据库,所以不需要执行数据库迁移命令!!# python38 manage.py makemigration# python38 manage.py migrate

.

三个html页面

userlist_pagehtml
        Title    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.1/jquery.js"></script>    {% load static %}        <script src="{% static "bootstrap-3.4.1-dist/js/bootstrap.min.js" %}"></script>

数据展示页

数据添加 {% for user_obj in user_data %} {% endfor %}
Id Name Age Operation
{{ user_obj.pk }} {{ user_obj.name }} {{ user_obj.age }} 编辑 删除
<script> $(".delBtn").click(function () { let res = confirm("你确定要删除吗???") if (res){}else{return false} }) {#给删除按钮加一个点击事件,触发确认框,根据确认框的返回值,来决定是否要删除数据#} {#如果返回值是true说明用户确实要删,什么操作都不用做,删除函数会自动删!!#} {#如果返回值是false说明用户不想删了,此时利用jQuery事件先执行绑定的事件然后return false取消掉自身的功能#} {#这样点a标签就只能触发绑定的单击事件,但是a标签自身的点击跳转到对应页面的功能就被取消掉了,就不执行删除函数了!#} </script>{# a标签的href=网址 点击a标签就会跳转到该网址去!就是朝该网址发了一个get请求!!!#}
useradd_pagehtml
        Title    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.1/jquery.js"></script>        {% load static %}        <script src="{% static "bootstrap-3.4.1-dist/js/bootstrap.min.js" %}"></script>    

数据添加页

username:

age:

{# 前端需要获取数据,并且发送给后端,目前只有form表单能实现!!#}

.

useredit_pagehtml
        Title    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.1/jquery.js"></script>         {% load static %}        <script src="{% static "bootstrap-3.4.1-dist/js/bootstrap.min.js" %}"></script>       

数据编辑页

username:

age:

.{# a标签的href=网址 点击a标签就会跳转到该网址去!就是朝该网址发了一个get请求!!!#}..form表单action后面不写默认朝当前页面提交数据!!..可以看出每一个a标签都带了额外的数据了!当我们点击按钮跳转到编辑页面的时候,网址路由的后面是跟了后缀的,这样我们用request.GET()就能拿到问号后面的信息,从而后端就知道你要编辑那条数据了!!!..可以看出随机点一个用户编辑按钮后,跳转的编辑页面,自动已经将用户数据放input框里面了!!.......

django请求生命周期流程图

这个图很重要 无论是学习阶段还是复习阶段django默认的网关接口  能够承受并发量很低 开发阶段用的!!!wsgiref web服务器网关接口模块 主要作用:帮我们解析http请求数据格式,帮我们处理请求数据的格式!!!uwsgi网关接口模块,程序上线之后用的!!!两个模块都是基于WSGI协议开发的学习流程路由层、视图层、模板层、模型层、组件、BBS项目

...

django路由层

1.针对路由匹配urls.py文件里面django2.X及以上   path()第一个参数写什么就匹配什么django1.X         path()第一个参数是 正则表达式无论什么版本django都自带加斜杠后缀的功能 也可以取消配置文件中 APPEND_SLASH = Falseslash 劈 砍 斜线--------------------------------------------------------------------------------------------------

.

2.转换器 将对应位置匹配到的数据转化成固定的数据类型!!!

正常情况下很多网站都会有很多相似的网址 如果我们每一个都单独开设路由不合理django2.X及以上版本路由动态匹配有转换器(五种) 记前两个就行了!!!----------------------------------------------------------------------------------------------------------------------------------------str:匹配除路径分隔符外的任何非空字符串。int:匹配0或者任意正整数。slug:匹配任意一个由字母或数字组成的字符串。uuid:匹配格式化后的UUID。path:能够匹配完整的URL路径 ps:还支持自定义转换器(自己写正则表达式匹配更加细化的内容)--------------------------------------------------------------path("index//", views.index_func)在用转化器捕捉一些数据的时候,index/后面所匹配到的内容会当成关键字参数传给后面的视图函数!!!打个比方我输入了网址:http://127.0.0.1:8000/index/aaaa/会接收到aaaa并转为字符串,以关键字产生传给views.index_func函数!!!index_func(实参request,info="转换器匹配到的类型转换之后的内容")由于我们的函数只定义了一个位置参数,并且是框架拿到请求数据整理好直接传给函数的我们并没有在函数定义阶段定于关键字参数,所以转换器得到的字符串,没法传给函数!!!路由这样写的目的是:比如接口前缀index/将来不知道要接什么后缀,但是我就想让index/后面接后缀,就可以这样用!!!---------------------------------------# 转换器 将对应位置匹配到的数据转换成固定的数据类型# index_func(实参request,info="转换器匹配到的类型转换之后的内容")path("index//", views.index_func)--------------------------------------------------------------------------------------------------path("index///", views.index_func)同理如果再加一个转换器!那么对应的自定义函数就要在加一个id参数进去,才能不报错这时候http://127.0.0.1:8000/index/aaaa/12235456/函数里面info参数就拿到了aaaa  id参数就拿到了12235456# index_func(实参request对象,info="转换器匹配到的类型转换之后的内容",id="转换器匹配到的类型转换之后的内容")当如如果在视图函数里面不需要用到,转换器匹配到的数据,有不写一个一个写对应的参数,就直接这样写就行了!!!def index_func(request, **kwargs):--------------------------------------------------------------------------------------------------

urlpatterns = [path("index/str:info/", views.index_func),]由于我们的函数只定义了一个位置参数,并且是框架拿到请求数据整理好直接传给函数的我们并没有在函数定义阶段定于关键字参数,所以转换器得到的字符串,没法传给函数!!!所以报错!!index_func(实参request,info="转换器匹配到的类型转换之后的内容")由于我们的函数只定义了一个位置参数,并且是框架拿到请求数据整理好直接传给函数的我们并没有在函数定义阶段定于关键字参数,所以转换器得到的字符串,没法传给函数!!!.也就是如果不想让函数报错,必须要在函数的定义阶段在括号里面加个info,才能不报错!!!...

3.正则匹配

django2.X及以上版本 urls.py 文件里面   re_path()第一个参数是正则正则匹配的特点:只要第一个正则表达式能够从用户输入的路由中匹配到数据,就算匹配成功!!!会立刻停止路由层其他的匹配,直接执行对应的视图函数只要正则表达式能够从用户输入的网址中,匹配到内容就算匹配成功,立刻触发后面的视图函数的运行!!并接受路由层的匹配!!!--------------------------------------------------------------------------------------------------路由的正则的最终版:把网址后缀的前后都限制死!!!re_path("^test/$", views.test)django1.X路由匹配使用的是url() 功能与django2.X及以上的re_path()一致from django.urls import path,re_path--------------------------------------------------------------------------------------------------

只要第一个正则表达式能够从用户输入的路由中匹配到数据就算匹配成功!!!会立刻停止路由层其他的匹配直接执行对应的视图函数路由testadd 也能被正则test 匹配上 所有就直接执行test的视图函数了!!!.也就是如果网址后缀testadd这样写,那testadd的视图函数永远执行不了!!!如何解决了?屁股后面加个斜杆就行了!!!输入网址后 http://127.0.0.1:8000/testadd django会自动给你添加一个斜杆这时候就匹配上了testadd/的路由了!!!...

4.正则匹配的无名有名分组

--------------------------------------------------无名分组re_path("^test/(\d{4})/", views.test)匹配开头是text/后面是4个数字的路由!!!会将括号内正则匹配到的内容!!!当做位置参数!!!传递给视图函数!!!正则表达式加括号就是分组!!!!如果有两个分组,函数里面就要多加两个位置参数!!!----------------------------------------------------------------------------------------------------有名分组re_path("^test/(?P\d{4})/", views.test)会将括号内正则匹配到的内容,当做关键字参数,传递给视图函数!!!注意上述的分组不能混合使用!!!----------------------------------------------------------------------------------------------------

....

反向解析

通过一个名字可以反向解析出一个结果 该结果可以访问到某个对应的路由基本使用1.路由匹配关系起别名    path("login001/", views.login, name="login_view")2.反向解析语法    html页面上模板语法{% url "login_view" %}    后端语法   reverse("login_view")        动态路由的反向解析path("func1//", views.func1_func, name="func1_view") html页面上模板语法 {% url "func1_view" "jason" %} 后端语法  reverse("func1_view", args=("嘿嘿嘿",))

作业

1.利用路由匹配与反向解析改写作业讲解2.整理今日内容及博客

关键词: 用户数据 正则表达式 位置参数