一、ORM关系建立

(一)ForeignKey(一对多)

  1. 外键字段建在多的那一方(多次引用)
  2. 外键字段在同步时,会自动在字段加_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(多对多)

  1. 被当做外键的表必须先创建,因此多对多的外键关系需要建立第三张表来专门处理
  2. 多对多的外键字段建在任意一方都可以,推荐建在查询速率高的一方
  3. 多对多的外键字段只是一个虚拟字段,不会再表中展示出来,只是起到一个高速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(一对一)

  1. 一对一的表关系,外键字段建在任意一方都可以,推荐建在查询频率较高的一方
  2. 外键字段也不用添加_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配置

  1. 正则表达式:一个正则表达式字符串
  2. views视图函数:一个可调用对象,通常为一个视图函数或一个指定视图函数路径的字符串
  3. 参数:可选的要传递给视图函数的默认参数(字典形式)
  4. 别名:可选的name参数
from django.conf.urls import url

urlpatterns = [
     url(正则表达式, views视图函数,参数,别名),
]

(2)正则表达式详解

  1. 正则匹配一旦匹配成功则不再继续,因此可加^$进行精确配置
  2. ^:以···开头,控制路由后缀前面部分
  3. $:以···结尾,控制路由后缀后面部分
  4. /:用来控制防止路由后缀前缀相同,比如,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

  1. settings.py文件中,没有此参数,但是默认参数APPEND_SLASH=True
  2. 作用:在浏览器发送请求时,检测到没有后缀/时,自动加上/并重定向到该网址
  3. 可在settings.py文件中,最后一行,配置APPEND_SLASH=False来关掉此功能

(二)分组匹配

  1. 无名分组:将分组内正则表达式匹配到的内容以位置参数传给视图函数,(pattern)
  2. 有名分组:将分组内正则匹配式匹配到的内容以关键字参数传给视图函数,(?P<name>pattern)
  3. 无名和有名分组不能混用,但是同种分组可以使用多次
  4. 正则表达式匹配出的参数永远都是字符串
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'),  # 路由和函数起别名
  1. 前端反向解析(url)

    <p><a href="{% url 'xxx' %}">111</a></p>
  2. 后端反向解析(reverse)

    from django.shortcuts import render,HttpResponse,redirect,reverse
    url = reverse('xxx')

(2)无名分组匹配

url(r'^home/(\d+)/', views.home,name='xxx'),  # 给路由与视图函数对应关系起别名
  1. 前端反向解析

    <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>
  2. 后端反向解析

    手动传入的参数 只需要满足能够被正则表达式匹配到即可

    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'),  # 给路由与视图函数对应关系起别名
  1. 前端反向解析

    <!--使用无名分组也可以-->
    <p><a href="{% url 'xxx' 12 %}">111</a></p>
    
    <!--规范写法-->
    <p><a href="{% url 'xxx' year=1232 %}">111</a></p>
  2. 后端反向解析

    # 可以使用无名分组
    url = reverse('xxx',args=(1,))
    
    # 规范写法
    url = reverse('xxx',kwargs={'year':213123})

(四)路由分发(include)

  1. 在django中,所有的app都可以有自己独立的urls,templates,static,因此,用django开发项目就可以完全做到多人分组开发,互相不干扰,每个人只开发自己的app
  2. 路由分发可以让总路由只做任务分发,具体的应用视图函数由应用的路由去做映射,从而解决项目的总路由匹配关系过多的问题
  3. 总路由分发时推荐使用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

  1. Django2.0中新增了一个path功能,传入的第一个参数不是正则表达式
  2. 用来解决:数据类型转换问题与正则表达式冗余问题

(三)转换器

(1)内置转换器

  1. str:匹配除了路径分隔符(/)之外的非空字符串,这是默认的形式
  2. int:匹配正整数,包含0。
  3. slug,匹配字母、数字以及横杠、下划线组成的字符串。
  4. uuid:匹配格式化的uuid,如 075194d3-6885-417e-a8a8-6c931e272f00。
  5. 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)自定义转换器

可以自定义参数转换的精度或长度

  1. 在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是两个数字,返回的结果也必须是两个数字
  2. 在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、路由层、版本差异、流程图的更多相关文章

  1. Django-1版本的路由层、Django的视图层和模板层

    一.Django-1版本的路由层(URLconf) URL配置(URLconf)就像Django所支撑网站的目录.它的本质是URL与要为该URL调用的视图函数之间的映射表:我们就是以这种方式告诉Dja ...

  2. Django框架之第三篇(路由层)--有名/无名分组、反向解析、路由分发、名称空间、伪静态

    一.Django请求生命周期 二.路由层  urls.py url()方法 第一个参数其实就是一个正则表达式,一旦前面的正则匹配到了内容,就不会再往下继续匹配,而是直接执行对应的视图函数. djang ...

  3. 第三章、Django之路由层

    目录 第三章.Django之路由层 一 路由的作用 二 简单的路由配置 三 分组 四 路由分发 五 反向解析 六 名称空间 七 django2.0版的re_path与path 第三章.Django之路 ...

  4. [Django框架之路由层匹配、有名 无名分组、反向解析、路由分发、名称空间、伪静态、本地虚拟环境、django版本区别]

    [Django框架之路由层匹配.有名 无名分组.反向解析.路由分发.名称空间.伪静态.本地虚拟环境.django版本区别] 路由层 路由即请求地址与视图函数的映射关系,如果把网站比喻成一本书,那路由就 ...

  5. orm之路由层

    一.简单配置 1.参数 第一个参数是正则表达式(如果要精准匹配:‘^publish/$’),或者加斜杠('^publish/') 第二个参数是视图函数(不要加括号) urlpatterns = [ u ...

  6. Django --- 路由层(urls)

    目录 1.orm表关系如何建立 2.django请求生命周期流程图 3.urls.py路由层 4.路由匹配 5.无名分组 6.有名分组 7.反向解析 8.路由分发 9.名称空间 10.伪静态 11.虚 ...

  7. django之路由层(反向解析)总结

    表关系的建立方式 表与表之间的关系就三种 一对一 OneToOne(to='') # to后面可以跟字符串的表名 也可以直接跟变量名表名(该表名必须在上面提前定义出来) 一对多 ForeignKey( ...

  8. django 路由层(反向解析)03

    目录 ORM表关系建立 Django请求生命周期流程图 urls.py 路由层 无名分组 有名分组 反向解析 无名分组的反向解析 有名分组的反向解析 以编辑功能为例 路由分发 名称空间 伪静态 虚拟环 ...

  9. Django路由层与视图层

    表与表之间建关系 图书管理系统为例 书籍表 出版社表 作者表 三个表之间的关系: 考虑表之间的关系:换位思考 1.书籍和出版社是一对多,外键字段建立在书籍表中 2.书籍和作者是多对多, 需要建立第三方 ...

随机推荐

  1. Codeforces Round #601 (Div. 2)

    传送门 A. Changing Volume 签到. Code /* * Author: heyuhhh * Created Time: 2019/11/19 22:37:33 */ #include ...

  2. poj 3070 矩阵计算Fibonacci

    地址 http://poj.org/problem?id=3070 大意是输入一个数字 输出位于Fibonacci数列该位置的数字模10000的结果 由于n比较大 0 ≤ n ≤ 1,000,000, ...

  3. 《icra16_slam_tutorial_tardos.pdf》

    icra16_slam_tutorial_tardos.pdf EKF: https://www.cnblogs.com/gaoxiang12/p/5560360.html 7. 小结 卡尔曼滤波是递 ...

  4. 给那些迷茫的人学习JAVA的一些建议?

    前语:我用了3年的时间,一步一步走到了现在,半途也有了解过其他的技能,也想过要转其他的言语,可是最终仍是坚持下来走Java这条路,希望我的经历能够帮忙到后来的人,要是觉得对你有帮忙的话,能够注重一下和 ...

  5. Tarjan在图论中的应用(三)——用Tarjan来求解2-SAT

    前言 \(2-SAT\)的解法不止一种(例如暴搜?),但最高效的应该还是\(Tarjan\). 说来其实我早就写过用\(Tarjan\)求解\(2-SAT\)的题目了(就是这道题:[2019.8.14 ...

  6. Paper | Deep Mutual Learning

    目录 1. 动机详述和方法简介 2. 相关工作 3. 方法 3.1 Formulation 3.2 实现 3.3 弱监督学习 4. 实验 4.1 基本实验 4.2 深入实验 [算法和公式很simple ...

  7. vue中\$refs、\$emit、$on的使用场景

    1.$emit的使用场景 子组件调用父组件的方法并传递数据注意:子组件标签中的时间也不区分大小写要用“-”隔开 子组件: <template> <button @click=&quo ...

  8. angularjs 一篇文章看懂自定义指令directive

     壹 ❀ 引 在angularjs开发中,指令的使用是无处无在的,我们习惯使用指令来拓展HTML:那么如何理解指令呢,你可以把它理解成在DOM元素上运行的函数,它可以帮助我们拓展DOM元素的功能.比如 ...

  9. LeetCode 217:存在重复元素 Contains Duplicate

    题目: 给定一个整数数组,判断是否存在重复元素. Given an array of integers, find if the array contains any duplicates. 如果任何 ...

  10. 使用Redis实现最近N条数据的决策

    前言 很多时候,我们会根据用户最近一段时间的行为,做出一些相应的策略,从而改变系统的运动轨迹. 举个简单的例子来说明一下: 假设A公司现在有两个合作伙伴(B和C),B和C都是提供天气数据的,现在A公司 ...