(day51)三、ORM、路由层、版本差异、流程图
一、ORM关系建立
(一)ForeignKey(一对多)
- 外键字段建在多的那一方(多次引用)
- 外键字段在同步时,会自动在字段加_id后缀,不需要手动加
from django.db import models
class Publish(models.Model):
title = models.CharField(max_length=32)
email = models.EmailField()
class Book(models.Model):
title = models.CharField(max_length=32)
email = models.DecimalField(max_digits=8,decimal_places=2) # 数字总共8位,小数两位
# 书和出版社是一对多,并且书是多的一方,所以外键字段在书表中
publish = models.ForeignKey(to = 'Publish') # to用来指代和哪张表有关系,默认关联主键字段
(二)ManyToManyField(多对多)
- 被当做外键的表必须先创建,因此多对多的外键关系需要建立第三张表来专门处理
- 多对多的外键字段建在任意一方都可以,推荐建在查询速率高的一方
- 多对多的外键字段只是一个虚拟字段,不会再表中展示出来,只是起到一个高速ORM创建第三张表的关系的作用
from django.db import models
class Author(models.Model):
name = models.CharField(max_length=32)
age = models.IntegerField()
class Book(models.Model):
title = models.CharField(max_length=32)
price = models.DecimalField(max_digits=8,decimal_places=2)
# 书跟作者是多对多的关系 外键字段建在任意一方都可以 但是建议你建在查询频率较高的那一方
author = models.ManyToManyField(to='Author') # django orm会自动帮你创建书籍和作者的第三张关系表
# author这个字段是一个虚拟字段 不能在表中展示出来 仅仅只是起到一个高速orm 建第三章表的关系的作用
(三)OneToOneField(一对一)
- 一对一的表关系,外键字段建在任意一方都可以,推荐建在查询频率较高的一方
- 外键字段也不用添加_id
from django.db import models
class Author(models.Model):
name = models.CharField(max_length=32)
age = models.IntegerField()
# 一对一的表关系 外键字段建在任意一方都可以,推荐建在查询频率较高的一方
author_detail = models.OneToOneField(to='Author_detail') # fk + unique
class Author_detail(models.Model):
phone = models.BigIntegerField()
addr = models.CharField(max_length=32)
二、django请求生命周期流程图
三、urls.py 路由层
(一)路由匹配
路由即请求地址和视图函数的映射关系
(1)URLconf配置
- 正则表达式:一个正则表达式字符串
- views视图函数:一个可调用对象,通常为一个视图函数或一个指定视图函数路径的字符串
- 参数:可选的要传递给视图函数的默认参数(字典形式)
- 别名:可选的name参数
from django.conf.urls import url
urlpatterns = [
url(正则表达式, views视图函数,参数,别名),
]
(2)正则表达式详解
- 正则匹配一旦匹配成功则不再继续,因此可加
^
和$
进行精确配置 ^
:以···开头,控制路由后缀前面部分$
:以···结尾,控制路由后缀后面部分/
:用来控制防止路由后缀前缀相同,比如,r'test'
和r'testadd'
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'test/', views.test), # 路由后缀为qqqtest/qqq仍可访问
url(r'^test/', views.test), # 路由后缀为test/qqq仍可访问
url(r'test/$', views.test), # 路由后缀为qqqtest/仍可访问
url(r'^test/$', views.test), # 路由后缀为test/才可访问
]
(3)APPEND_SLASH
- settings.py文件中,没有此参数,但是默认参数APPEND_SLASH=True
- 作用:在浏览器发送请求时,检测到没有后缀
/
时,自动加上/
并重定向到该网址 - 可在settings.py文件中,最后一行,配置
APPEND_SLASH=False
来关掉此功能
(二)分组匹配
- 无名分组:将分组内正则表达式匹配到的内容以位置参数传给视图函数,
(pattern)
- 有名分组:将分组内正则匹配式匹配到的内容以关键字参数传给视图函数,
(?P<name>pattern)
- 无名和有名分组不能混用,但是同种分组可以使用多次
- 正则表达式匹配出的参数永远都是字符串
url(r'^test/([0-9]{4})/', views.test) # 无名分组
url(r'^testadd/(?P<year>\d+)/', views.testadd) # 有名分组
url(r'^index/(\d+)/(?P<year>\d+)/', views.index) # 不能混合使用,会报错
url(r'^index/(\d+)/(\d+)/', views.index), # 可以使用多次无名分组
url(r'^index/(?P<args>\d+)/(?P<year>\d+)/', views.index), # 可以使用多次有名分组
(三)反向解析
根据一个别名,动态解析出一个结果,该结果可以直接访问对应url
(1)正常匹配
url(r'^home/', views.home,name='xxx'), # 路由和函数起别名
前端反向解析(url)
<p><a href="{% url 'xxx' %}">111</a></p>
后端反向解析(reverse)
from django.shortcuts import render,HttpResponse,redirect,reverse url = reverse('xxx')
(2)无名分组匹配
url(r'^home/(\d+)/', views.home,name='xxx'), # 给路由与视图函数对应关系起别名
前端反向解析
<p><a href="{% url 'xxx' 12 %}">111</a></p> <p><a href="{% url 'xxx' 1324 %}">111</a></p> <p><a href="{% url 'xxx' 14324 %}">111</a></p> <p><a href="{% url 'xxx' 1234 %}">111</a></p>
后端反向解析
手动传入的参数 只需要满足能够被正则表达式匹配到即可
url = reverse('xxx',args=(1,)) url1 = reverse('xxx',args=(3213,)) url2 = reverse('xxx',args=(2132131,))
(3)有名分组匹配
url(r'^home/(?P<year>\d+)/', views.home,name='xxx'), # 给路由与视图函数对应关系起别名
前端反向解析
<!--使用无名分组也可以--> <p><a href="{% url 'xxx' 12 %}">111</a></p> <!--规范写法--> <p><a href="{% url 'xxx' year=1232 %}">111</a></p>
后端反向解析
# 可以使用无名分组 url = reverse('xxx',args=(1,)) # 规范写法 url = reverse('xxx',kwargs={'year':213123})
(四)路由分发(include)
- 在django中,所有的app都可以有自己独立的urls,templates,static,因此,用django开发项目就可以完全做到多人分组开发,互相不干扰,每个人只开发自己的app
- 路由分发可以让总路由只做任务分发,具体的应用视图函数由应用的路由去做映射,从而解决项目的总路由匹配关系过多的问题
- 总路由分发时推荐使用
include('应用名.urls')
# 子路由1.py
from django.conf.urls import url
from app01 import views
urlpatterns = [
url('^reg/',views.reg)
]
# 子路由2.py
from django.conf.urls import url
from app02 import views
urlpatterns = [
url('^reg/',views.reg)
]
# 总路由.py
######## 第一种写法
from app01 import urls as app01_urls
from app02 import urls as app02_urls
urlpatterns = [
url(r'^admin/', admin.site.urls), # url第一个参数是一个正则表达式
# 路由分发
url(r'^app01/',include(app01_urls)), # 路由分发需要注意总路由里面不能以$结尾
url(r'^app02/',include(app02_urls)),
]
######## 第二种写法(推荐写法)
urlpatterns = [
url(r'^app01/',include('app01.urls')),
url(r'^app02/',include('app02.urls'))
]
(五)别名冲突
当多个app中出现了别名冲突时,,会出现访问错乱的问题
(1)名称空间
路由分发的时候可以给每一个app创建一个名称空间,然后在反向解析的时候可以选择到底去哪个名称空间中查找别名
url(r'^app01/',include('app01.urls',namespace='app01')),
url(r'^app02/',include('app02.urls',namespace='app02'))
# 后端
print(reverse('app01:reg'))
print(reverse('app02:reg'))
# 前端
<a href="{% url 'app01:reg' %}"></a>
<a href="{% url 'app02:reg' %}"></a>
(2)应用名前缀
起别名的时候统一加上应用名前缀
urlpatterns = [
url(r'^reg/',views.reg,name='app02_reg')
]
urlpatterns = [
url('^reg/',views.reg,name='app01_reg')
]
四、伪静态
将一个动态网页伪装成一个静态网页,以此来提升搜索引擎SEO查询频率和搜藏力度
urlpatterns = [
url('^reg.html',views.reg)
]
五、dangjo版本区别
(一)re_path
Django2.0中的re_path与django1.0的url一样,传入的第一个参数都是正则表达式
from django.urls import re_path # django2.0中的re_path
from django.conf.urls import url # 在django2.0中同样可以导入1.0中的url
urlpatterns = [
# 用法完全一致
url(r'^app01/', include(('app01.urls','app01'))),
re_path(r'^app02/', include(('app02.urls','app02'))),
]
(二)path
- Django2.0中新增了一个path功能,传入的第一个参数不是正则表达式
- 用来解决:数据类型转换问题与正则表达式冗余问题
(三)转换器
(1)内置转换器
- str:匹配除了路径分隔符(/)之外的非空字符串,这是默认的形式
- int:匹配正整数,包含0。
- slug,匹配字母、数字以及横杠、下划线组成的字符串。
- uuid:匹配格式化的uuid,如 075194d3-6885-417e-a8a8-6c931e272f00。
- path,匹配任何非空字符串,包含了路径分隔符(/)(不能用?)
path('articles/<int:year>/<int:month>/<slug:other>/', views.article_detail)
# 针对路径http://127.0.0.1:8000/articles/2009/123/hello/,path会匹配出参数year=2009,month=123,other='hello'传递给函数article_detail
(2)自定义转换器
可以自定义参数转换的精度或长度
在app01下新建文件path_ converters.py,文件名可以随意命名
class MonthConverter: regex='\d{2}' # 属性名必须为regex def to_python(self, value): return int(value) def to_url(self, value): return value # 匹配的regex是两个数字,返回的结果也必须是两个数字
在urls.py中,使用
register_converter
将其注册到URL配置中:from django.urls import path,register_converter from app01.path_converts import MonthConverter register_converter(MonthConverter,'mon') from app01 import views urlpatterns = [ path('articles/<int:year>/<mon:month>/<slug:other>/', views.article_detail,name='aaa'), ]
(day51)三、ORM、路由层、版本差异、流程图的更多相关文章
- Django-1版本的路由层、Django的视图层和模板层
一.Django-1版本的路由层(URLconf) URL配置(URLconf)就像Django所支撑网站的目录.它的本质是URL与要为该URL调用的视图函数之间的映射表:我们就是以这种方式告诉Dja ...
- Django框架之第三篇(路由层)--有名/无名分组、反向解析、路由分发、名称空间、伪静态
一.Django请求生命周期 二.路由层 urls.py url()方法 第一个参数其实就是一个正则表达式,一旦前面的正则匹配到了内容,就不会再往下继续匹配,而是直接执行对应的视图函数. djang ...
- 第三章、Django之路由层
目录 第三章.Django之路由层 一 路由的作用 二 简单的路由配置 三 分组 四 路由分发 五 反向解析 六 名称空间 七 django2.0版的re_path与path 第三章.Django之路 ...
- [Django框架之路由层匹配、有名 无名分组、反向解析、路由分发、名称空间、伪静态、本地虚拟环境、django版本区别]
[Django框架之路由层匹配.有名 无名分组.反向解析.路由分发.名称空间.伪静态.本地虚拟环境.django版本区别] 路由层 路由即请求地址与视图函数的映射关系,如果把网站比喻成一本书,那路由就 ...
- orm之路由层
一.简单配置 1.参数 第一个参数是正则表达式(如果要精准匹配:‘^publish/$’),或者加斜杠('^publish/') 第二个参数是视图函数(不要加括号) urlpatterns = [ u ...
- Django --- 路由层(urls)
目录 1.orm表关系如何建立 2.django请求生命周期流程图 3.urls.py路由层 4.路由匹配 5.无名分组 6.有名分组 7.反向解析 8.路由分发 9.名称空间 10.伪静态 11.虚 ...
- django之路由层(反向解析)总结
表关系的建立方式 表与表之间的关系就三种 一对一 OneToOne(to='') # to后面可以跟字符串的表名 也可以直接跟变量名表名(该表名必须在上面提前定义出来) 一对多 ForeignKey( ...
- django 路由层(反向解析)03
目录 ORM表关系建立 Django请求生命周期流程图 urls.py 路由层 无名分组 有名分组 反向解析 无名分组的反向解析 有名分组的反向解析 以编辑功能为例 路由分发 名称空间 伪静态 虚拟环 ...
- Django路由层与视图层
表与表之间建关系 图书管理系统为例 书籍表 出版社表 作者表 三个表之间的关系: 考虑表之间的关系:换位思考 1.书籍和出版社是一对多,外键字段建立在书籍表中 2.书籍和作者是多对多, 需要建立第三方 ...
随机推荐
- Codeforces Round #601 (Div. 2)
传送门 A. Changing Volume 签到. Code /* * Author: heyuhhh * Created Time: 2019/11/19 22:37:33 */ #include ...
- poj 3070 矩阵计算Fibonacci
地址 http://poj.org/problem?id=3070 大意是输入一个数字 输出位于Fibonacci数列该位置的数字模10000的结果 由于n比较大 0 ≤ n ≤ 1,000,000, ...
- 《icra16_slam_tutorial_tardos.pdf》
icra16_slam_tutorial_tardos.pdf EKF: https://www.cnblogs.com/gaoxiang12/p/5560360.html 7. 小结 卡尔曼滤波是递 ...
- 给那些迷茫的人学习JAVA的一些建议?
前语:我用了3年的时间,一步一步走到了现在,半途也有了解过其他的技能,也想过要转其他的言语,可是最终仍是坚持下来走Java这条路,希望我的经历能够帮忙到后来的人,要是觉得对你有帮忙的话,能够注重一下和 ...
- Tarjan在图论中的应用(三)——用Tarjan来求解2-SAT
前言 \(2-SAT\)的解法不止一种(例如暴搜?),但最高效的应该还是\(Tarjan\). 说来其实我早就写过用\(Tarjan\)求解\(2-SAT\)的题目了(就是这道题:[2019.8.14 ...
- Paper | Deep Mutual Learning
目录 1. 动机详述和方法简介 2. 相关工作 3. 方法 3.1 Formulation 3.2 实现 3.3 弱监督学习 4. 实验 4.1 基本实验 4.2 深入实验 [算法和公式很simple ...
- vue中\$refs、\$emit、$on的使用场景
1.$emit的使用场景 子组件调用父组件的方法并传递数据注意:子组件标签中的时间也不区分大小写要用“-”隔开 子组件: <template> <button @click=&quo ...
- angularjs 一篇文章看懂自定义指令directive
壹 ❀ 引 在angularjs开发中,指令的使用是无处无在的,我们习惯使用指令来拓展HTML:那么如何理解指令呢,你可以把它理解成在DOM元素上运行的函数,它可以帮助我们拓展DOM元素的功能.比如 ...
- LeetCode 217:存在重复元素 Contains Duplicate
题目: 给定一个整数数组,判断是否存在重复元素. Given an array of integers, find if the array contains any duplicates. 如果任何 ...
- 使用Redis实现最近N条数据的决策
前言 很多时候,我们会根据用户最近一段时间的行为,做出一些相应的策略,从而改变系统的运动轨迹. 举个简单的例子来说明一下: 假设A公司现在有两个合作伙伴(B和C),B和C都是提供天气数据的,现在A公司 ...