☆Django☆---表的设计 生命周期 分组 解析 路由层 视图层
图书管理系统的 表 设计
图书管理系统分别有三张表 作者表 书籍表 出版社表 他们 的对应关系为
如何在 Django中建立表与表之间的关系?
首先我们需要在 app文件里 的 models创建出 这三张表 然后做对应关系
复习Django的操作: 1.创建好app后需要 将app添加到INSTALLED_APP = [] 里面
2.在Django中添加mysql数据库 >>>点击 侧边栏中的 database >>>然后左上角的加号 >>> 点击 Data source (数据来源) >>>选择mysql
3.在app文件 或者 Django文件下的 __init__文件里 导入 pymysql 文件 使用 pymysql.install_as_Mysqldb() 代码来指定使用的模块
4.需要在配置文件里 修改 Django默认使用连接数据库的模块 改为 pymysql 在settings文件里找到 DATABASES 如图4修改:
注意 需要 先下载她让下载的驱动(driver) 文件 然后选择 driver 5.1 启动就行了
# Create your models here. class Book(models.Model): id = models.AutoField(primary_key=True) title = models.CharField(max_length=32) price = models.IntegerField(null=True) # 多对多 author = models.ManyToManyField(to='Author') publish = models.ForeignKey(to='Publish') class Author(models.Model): id = models.AutoField(primary_key=True) name = models.CharField(max_length=32) class Publish(models.Model): id = models.AutoField(primary_key=True) name = models.CharField(max_length=32)
使用代码来创建表与表之间的关系
一对多 ForeignKey(to='Publish')
一对一 OneToOneField(to='AuthorDetail')
多对多 ManyToManyField(to='Author')
最后强调! 只要牵扯到models及数据库操作字段 后 必须 要数据库 迁移
代码 python3 manage.py makemigrations
python3 manage.py migrate
Django请求生命周期图
路由层
我们会发现 在 urlpatterns (patterns 花样 模型 形态)中的 url(......,) 的第一个参数 是一个正则表达式
且 先记住 在 浏览器 输入的 后缀 一旦匹配到了 内容 就不会 往下继续匹配 而是 直接执行相应的视图函数 好比如:
url(r'^data/', 功能) url(r'^datasssss/, 功能') 他就会 直接执行 data相应的视图函数
斜杆
Django在路由匹配的时候 当你没有在 浏览器中敲最后的斜杆时 django会先拿着你没有敲斜杆的内容去匹配 如果没有 匹配上 会让浏览器 在末尾 添加斜杆后 再次发一次 请求在匹配 如果还是匹配不上的话就会报错!
如果你想取消该机制 不想做二次匹配的话 可以在 settings文件中指定
APPEND_SLASH = False # 默认参数是True slash(斜线)
无名分组
url(r'^test/([0-9]{4})/', views.test) 0到9 4位
路由匹配的时候 会将括号内的正则表达式匹配到的内容 当做位置参数 传给 视图函数 这么说 的话 他的参数就不止request了
有名分组
url(r'^test/(?P<year>\d+)/', views.test)
在括号内 ?p< > 就是 起别名
路由匹配的时候 会将括号内正则表达式匹配到的内容 当做关键字参数传递给视图函数
此时你的 位置参数就可以使用 他起的别名了
# 无名有名不能混合使用 !!! url(r'^test/(\d+)/(?P<year>\d+)/', views.test),
但是用一种分组下 可以使用多个 # 无名分组支持多个 # url(r'^test/(\d+)/(\d+)/', views.test), # 有名分组支持多个 # url(r'^test/(?P<year>\d+)/(?P<xx>\d+)/', views.test),
这样的话 我们的关键字就有两个了
匹配主页
url(r'^$',views.home)
反向解析
本质:本质其实就是 给你返回一个能够返回对应的 url的地址
1.我们需要给url 和 视图 函数起别名 例如
url(r'^index/$',views.index,name='kkk')
2.反向解析
后端的反向解析
后端可以在任意位置 通过reverse 方向解析出 对应的url
from django.shortcuts import render,HttpResponse,redirect,reverse 小白必回三板斧 后加入 reverser reverse('kkk')
shortcuts(快捷方式)
前端的反向解析
{% url 'kkk' %}
应用场景 防止代码写死了 假如说你的html中的 a 标签 有1000个 指向 路由 /index/ 但是你的产品经理 突然说 你给老子 把 那个 url 的参数改了 那么这1000个a 标签就gg 了 我们 就可以先给 路由和视图函数起别名 标签 name='kkk'
我们 前端页面中的a标签括号内使用 {%url 'kkk'%} 就可以反向解析到 你 url后缀了 就不怕你变了 同样 我们 还可以 在 后端 中使用 reverser('')内填写你起的别名 就可以反向解析到他的 url了
无名分组反向解析 url(r'^index/(\d+)/$',views.index,name='kkk') 后端反向解析 reverse('kkk',args=(1,)) # 后面的数字通常都是数据的id值 前端反向解析 {% url 'kkk' 1%} # 后面的数字通常都是数据的id值
有名分组反向解析 同无名分组反向解析意义的用法 url(r'^index/(?P<year>\d+)/$',views.index,name='kkk') 后端方向解析 print(reverse('kkk',args=(1,))) # 推荐你使用上面这种 减少你的脑容量消耗 print(reverse('kkk',kwargs={'year':1})) 前端反向解析 <a href="{% url 'kkk' 1 %}">1</a> # 推荐你使用上面这种 减少你的脑容量消耗 <a href="{% url 'kkk' year=1 %}">1</a> 注意:在同一个应用下 别名千万不能重复!!!
路由分发
当你的Django项目过于庞大的时候 路由与视图函数对应关系就特别的多而乱 那么我们的总路由 url.py 的代码就太过冗余 不易维护
每一个应用都可以有自己的 url.py static.py templates文件夹
基于以上的条件 就可以实现多人分组开发 等开发完之后 就可以创建 一个 新的 Django项目 把app都注册了 加入
在总路由实现路由分发 而不再做路由匹配 交给 app中的 url 来匹配
当你的视图函数比较多的时候 你也可以创建一个 views 文件夹 里面可以 根据 不同的 功能创建不同的文件
单词 include (包含)
在 url.py中的 urlpatterns = [
url(r'^app01',include('app01.urls'))
] 单词 >> patterns 模式
也可以使用模块的导入的方式 来 写
from app01 import urls as app01_urls url(r'^app01',include(app01_urls))
复习Django创建项目以及app
以及创建 Django项目的代码 先下载 Django 版本为 1.11.11
确认是否下载成功
出现很多代码就是下载成功了
创建Django项目 一定要先找到指定的文件夹 使用cd切换 单词 project 项目
创建app的两种方法
使用命名来启动 Django项目
注意 用命令行创建django项目 不会自动新建templates模板文件夹
需要你自己手动创建 并且需要你自己去settings.py文件中注册该文件路径
名称空间
多个app起了相同的别名 这个时候反向解析的时候 不会 自动识别应用前缀
这个时候就需要用到名称空间
from django.conf.urls import url
总路由 url(r'^app01/',include('app01.urls',namespace='app01')) url(r'^app02/',include('app02.urls',namespace='app02')) 后端解析的时候 reverse('app01:index') reverse('app02:index') 前端解析的时候 {% url 'app01:index' %} {% url 'app02:index' %}
伪静态
静态页面:数据是死的, 万年不变的
伪静态网页的设计就是为了 增加 百度的搜索引擎 seo的查询力度
所有的搜索引擎其实都是一个巨大的爬虫程序
网站优化相关 通过伪静态确实可以提高你的网站被查询出来的概率
但是再怎么优化也抵不过RMB玩家
虚拟环境 一般情况下 我们会给每一个项目 配备该项目所需要的模块 不需要的一概不装 虚拟环境 就类似于为每个项目量身定做的解释器环境 如何创建虚拟环境 每创建一个虚拟环境 就类似于你又下载了一个全新的python解释器 django版本的区别 django1.X跟django2.X版本区别 路由层1.X用的是url 而2.X用的是path 2.X中的path第一个参数不再是正则表达式,而是写什么就匹配什么 是精准匹配 当你使用2.X不习惯的时候 2.X还有一个叫re_path 2.x中的re_path就是你1.X的url 虽然2.X中path不支持正则表达式 但是它提供了五种默认的转换器 1.0版本的url和2.0版本的re_path分组出来的数据都是字符串类型 默认有五个转换器,感兴趣的自己可以课下去试一下 str,匹配除了路径分隔符(/)之外的非空字符串,这是默认的形式 int,匹配正整数,包含0。 slug,匹配字母、数字以及横杠、下划线组成的字符串。 uuid,匹配格式化的uuid,如 075194d3-6885-417e-a8a8-6c931e272f00。 path,匹配任何非空字符串,包含了路径分隔符(/)(不能用?
视图层 1.小白必会三板斧 1.HttpResponse 2.render 3.redirect django视图函数必须要给返回一个HttpResponse对象 前后端分离 前端一个人干(前端转成自定义对象) JSON.stringify() json.dumps() JSON.parse() json.loads() 后端另一个干(python后端用字典) 只要涉及到数据交互,一般情况下都是用的json格式 后端只负责产生接口,前端调用该接口能拿到一个大字典 后端只需要写一个接口文档 里面描述字典的详细信息以及参数的传递 2.JsonReponse from django.http import JsonResponse def index(request): data = {'name':'jason好帅哦 我好喜欢','password':123} l = [1,2,3,4,5,6,7,8] # res = json.dumps(data,ensure_ascii=False) # return HttpResponse(res) # return JsonResponse(data,json_dumps_params={'ensure_ascii':False}) return JsonResponse(l,safe=False) # 如果返回的不是字典 只需要修改safe参数为false即可 3.上传文件 form表单上传文件需要注意的事项 1.enctype需要由默认的urlencoded变成formdata 2.method需要由默认的get变成post (目前还需要考虑的是 提交post请求需要将配置文件中的csrf中间件注释) 如果form表单上传文件 后端需要在request.FILES获取文件数据 而不再是POST里面 request.method request.GET request.POST request.FILES request.path # 只回去url后缀 不获取?后面的参数 request.get_full_path() # 后缀和参数全部获取