ORM表关系建立

换位思考,先粘在一张表上面分析, 然后再站在另一张表上分析

一对一

外键字段创建在任意一张表都可以,简易在查询频率较高的一方添加

OneToOneField

models.OneToOneField(to='Author_detail')  # fk + unique

一对多

外键字段创建在多的那一方

ForeignKey

models.ForeignKey(to='Publish')  # to用来指代跟哪张表有关系 默认关联的就是表的主键字段

多对多

外键关系需要创建第三张表来处理。

ManyToManyField

models.ManyToManyField(to='Author')  # django orm会自动帮你创建第三张关系表

Django 请求生命周期

url 路由层

urlpatterns = [
url(r'^admin/', admin.site.urls),
]

url的第一个参数其实就是一个正则表达式,只要该正则表达式能够匹配到内容,就会立刻执行后面的视图函数,不再往下继续匹配。

路由匹配

Django settings.py配置文件中默认没有 APPEND_SLASH 这个参数,但 Django 默认这个参数为 APPEND_SLASH = True。 其作用就是自动在网址结尾加'/'。

我们定义了urls.py:

from django.conf.urls import url
from app01 import views urlpatterns = [
url(r'^blog/$', views.blog),
]

其效果就是:

访问 http://www.example.com/blog 时,默认将网址自动转换为 http://www.example/com/blog/

如果在settings.py中设置了 APPEND_SLASH=False,此时我们再请求 http://www.example.com/blog 时就会提示找不到页面。

Django 路由匹配的规律:

  1. 先是不加斜杠,先匹配依次试试,
  2. 如果匹配不上,会让浏览器重定向,url最后加上斜杠再次匹配一次,
  3. 如果还是匹配不上就报错了。
  4. 并且不会匹配GET请求?后面携带的参数

无名分组

将分组内正则表达式匹配到的内容当做位置参数传递给视图函数

url(r'^test/([0-9]{4})/', views.test)

访问的url:http://127.0.0.1/test/1111

# 当你的路由中有分组的正则表达式  那么在匹配到内容
# 执行视图函数的时候 会将分组内正则表达式匹配到的内容当做位置参数传递给视图函数
def test(request,xxx):
'''
此时url有第二个参数,会传递给视图函数位置参数传进来。
如果不写接收的位置参数则会报错
test() takes 1 positional argument but 2 were given
'''
print(xxx) # 1111
pass

有名分组

将分组内正则表达式匹配到的内容当做关键字参数传递给视图函数

url(r'^test/(?P<year>[0-9]{4})/', views.test)

访问的url:http://127.0.0.1/test/1111

# 当你的路由中有分组的正则表达式  那么在匹配到内容
# 执行视图函数的时候 会将分组内正则表达式匹配到的内容当做关键字参数传递给视图函数
def test(request,year):
'''
此时url有第二个参数,会传递给视图函数关键字参数传进来。
如果不写接收的关键字参数则会报错
testadd() got an unexpected keyword argument 'year'
'''
print(year) # 1111
pass

利用有名个无名分组 我们就可以在调用视图函数之前给函数传递额外的参数

注意:无名分组和有名分组不能混合使用

但是同一种分组的情况下 可以使用多次,

无名可以有多个

有名可以有多个

反向解析

给路由匹配设置一个别名,

根据这个别名,动态解析出一个结果,该结果可以直接访问对应的url。

路由匹配条件无分组的情况的反向解析

urls.py:
url(r'^home/',views.home,name='hm'),
url(r'^index/$',views.index), views.py:
def home(request):
return HttpResponse(reverse('hm')) def index(request):
print(reverse('hm')) # /home/
return render(request,'test.html') test.html:
<body>
<div>TEST</div>
<p><a href="{% url 'hm' %}">点我点我</a></p>
</body> 当我们在浏览器URL输入http://127.0.0.1:8000/index/的时候,
python后端进行reverse反向解析成 别名为'hm'的路径前缀,也就是home路径,
用test.html 页面渲染,html也可以使用反向解析 python后端使用反向解析:
reverse('hm')
前端html使用反向解析:
{% url 'hm' %}
将路径解析为/home/。

无名分组情况的反向解析

urls.py:
url(r'^home/(\d+)/',views.home,name='hm'),
url(r'^index/',views.index), views.py:
def home(request,xxx):
# 使用无名分组,视图函数必须写位置参数
print(xxx)
return HttpResponse('ok') def index(request):
print(reverse('hm',args=(1,))) # 无名分组需要手动给别名传递一个参数才能匹配上,这个参数会传递到视图函数当做位置参数。
return render(request,'test.html') test.html:
<body>
<div>TEST</div>
<p><a href="{% url 'hm' 1 %}">点我点我</a></p>
</body> 当一个无名分组使用别名的时候,在浏览器URL输入http://127.0.0.1:8000/index/,python后端进行reverse反向解析成 别名为'hm'的路径前缀,也就是home路径,需要手动给解析出来的路径加参数,不然匹配不成功
用test.html 页面渲染,并且html使用反向解析,也需要手动传入参数 python后端使用反向解析:
reverse('hm',args=(1,))
前端html使用反向解析:
{% url 'hm' 1 %}
将路径解析为/home/1。

有名分组的反向解析

urls.py:
url(r'^home/(?P<year>\d+)/',views.home,name='hm'),
url(r'^index/',views.index), views.py:
def home(request,year):
# 使用有名分组,视图函数必须写关键字参数
print(year)
return HttpResponse('ok') def index(request):
print(reverse('hm',args=(1,))) # 这样也可以,但不正规
print(reverse('hm',kwargs={"year":1})) # 最正规的写法,因为有名分组传入的是关键字参数,用kwargs参数来表示
return render(request,'test.html') test.html:
<body>
<div>TEST</div>
<p><a href="{% url 'hm' 1 %}">点我点我</a></p> # 这样也可以,但不正规
<p><a href="{% url 'hm' year=1 %}">点我点我</a></p> # 最正规的写法,因为有名分组传入的是关键字参数
</body> 当一个无名分组使用别名的时候,在浏览器URL输入http://127.0.0.1:8000/index/,python后端进行reverse反向解析成 别名为'hm'的路径前缀,也就是home路径,需要手动给解析出来的路径加参数,不然匹配不成功。
用test.html 页面渲染,并且html使用反向解析,也需要手动传入参数 python后端使用反向解析:
reverse('hm',kwargs={"year":1})
前端html使用反向解析:
{% url 'hm' year=1 %}
将路径解析为/home/1。

例子

伪代码以编辑用户信息为例,演示具体用法:

urls.py:

url(r'^edit_user/(\d+)',views.edit_user,name='edit'),

views.py:
def edit_user(request,edit_id):
# 查出来所有 user_list
# edit_id 就是用户想要编辑数据的主键值
print(edit_id)
return render(request,'edit_user.html',{"user_list":user_list}) edit_user.hmtl:
{% for user_obj in user_list %}
<a href="/edit_user/{{ user_obj.id }}">编辑</a>
<a href="{% url 'edit' user_obj.id %}">编辑</a>
{% endfor %}

路由分发

前言,在django中所有的app都可以有自己的独立的urls.py、templates、static文件夹

那么正是由于这个特点,你的django项目可以由多个人一起开发。小组长最后只需要把所有的开发的app整合到一个空的django项目里面,在settings配置文件里注册就可以了。

路由分发解决的就是项目的总路由匹配关系过多的情况,使用路由分发 会将总路由不再做匹配的活 而仅仅是做任务分发

我们新建一个app02,现在我的目录结构是:

python3 manage.py startapp app02
  • app01
  • app02
  • mysite
  • static
  • templates
  • manage.py

好了之后

我们在app01目录中创建urs.py

app01/urls.py:
from app01 import views
from django.conf.urls import url
urlpatterns = [
url(r'^reg/',views.reg),
] app01/views.py:
def reg(request):
return HttpResponse("app01 reg") -----------------------------------
app02/urls.py:
from app02 import views
from django.conf.urls import url
urlpatterns = [
url(r'^reg/',views.reg),
] app02/views.py:
def reg(request):
return HttpResponse("app02 reg") 总urls:mysite/urls.py:
from app01 import urls as app01_urls
from app02 import urls as app02_urls
urlpatterns = [
url(r'^app01/',include(app01_urls)),
url(r'^app02/',include(app02_urls)),
] 或者更省事的写法,不用把两个app的urls.py导过来:
urlpatterns = [
url(r'^app01/',include('app01.urls')),
url(r'^app02/',include('app02.urls')),
] 最终效果,在浏览器url中输入
http://127.0.0.1:8000/app01/reg # app01 reg
http://127.0.0.1:8000/app02/reg # app02 reg

名称空间

当多个app中出现了起别名冲突的情况 你在做路由分发的时候 可以给每一个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> 其实不用这么麻烦,
参考建议
起别名的时候统一加上应用名前缀,这样你的别名就不会重复了。
urlpatterns = [url(r'^reg/',views.reg,name='app01_reg')]
urlpatterns = [url(r'^reg/',views.reg,name='app02_reg')]

伪静态

将一个动态网页伪装成一个静态的网页,来提高搜索引擎SEO的查询频率,提高网站的曝光度!

怎么做呢,比如博客园是一个动态网站,但是看起来像一个静态网站,是因为每篇文章都有后缀名.html

那么我们也可以写,在路由匹配规则中写上

# https://www.cnblogs.com/qinyujie/p/11394671.html

url(r'^article/(\d+).html',views.article)

虚拟环境

虚拟环境就相当于重新下载了一个纯净的python解释器,之后项目用这个虚拟环境,你需要什么就安装什么,与系统环境上存在的软件不冲突。

Django版本区别

urls.py路由匹配的方法有区别。

django 1.X

导入的模块是

from django.conf.urls import url

urlpatterns 中 url 对应的是正则表达式,

如下:

from django.conf.urls import url
urlpatterns = [
url = ('test',view.test)
]

django 2.X

导入的模块是from django.urls import re_path,path

path中第一个参数不支持正则表达式,写了什么就只能匹配什么,匹配不到就报错。

django 2.X 觉得你习惯了之前的正则表达式来匹配,特别人性化 ,

提供一个re_path方法,这个方法就是1.X版本中的url()

如下:

from django.urls import path,re_path
urlpatterns = [
path = ('test',view.test),
re_path = (r'^test/(\d+)',view.test)
]

django 2.X的版本中还提供了五种转换器,

  • str:匹配除路径分隔符/外的字符串
  • int:匹配自然数
  • slug:匹配字母,数字,横杠及下划线组成的字符串
  • uuid:匹配uuid形式的数据
  • path:匹配任何字符串,包括路径分隔符/
urlpatterns = [
path = ('test/<str:\d+>',view.test)
path = ('test/<int:\d+>',view.test)
path = ('test/<slug:\d+>',view.test)
path = ('test/<uuid:\d+>',view.test)
path = ('test/<path:\d+>',view.test)
]

除了内置的五种转换器外,还可以自定义自己的转换器。

  • 在应用文件夹下创建converter.py文件
  • 在converter.py文件中创建自定义类
  • 在类中定义regex 正则,to_python方法,to_url方法

class CVT185Phone:
regex = '185\d{8}'
def to_python(self, value):
return int(value)
def to_url(self, value):
return '%11d' % value from django.urls import register_converter
from app.converter import CVT185phone
register_converter(CVT185phone,'phone185') path('page/<phone185:msg>/',views.page,name="pages")

小例子

通过路由分发,使用app01上传文件的功能上传一个文件;

mysite/urls.py
urlpatterns = [
url(r'^app01/',include('app01.urls')),
url(r'^app02/',include('app02.urls')),
] app01/urls.py
from app01 import views
from django.conf.urls import url
urlpatterns = [
url(r'^upload/',views.upload,name='app01_upload'),
] app01/views.py
from django.shortcuts import reverse,render,HttpResponse,redirect
def upload(request):
if request.method == "POST":
print(request.FILES)
file_obj = request.FILES.get("myfile")
with open(file_obj.name,"wb") as f:
for i in file_obj:
f.write(i)
return render(request,'upload.html') templates/upload.html
<body>
<form action="" method="post" enctype="multipart/form-data">
请选择文件
<input type="file" name="myfile">
<input type="submit" class="btn btn-primary">提交
</form>

Django之深入了解路由层的更多相关文章

  1. django 实战篇之路由层

    路由层 如何给网页添加首页及尾页 urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'test',views.test), url(r'te ...

  2. day 45 Django 的初识2 路由层,视图层,模板层

    前情提要: 今天继续学习Django 的内容, 今天主要和渲染相关 1>配置路由 >2:写函数 >3 指向url 一:路由层 1:配置静态支持文件 1:路由层的简单配置 >dj ...

  3. Django的日常-路由层

    目录 Django的日常-2 路由层 有名分组和无名分组 反向解析 路由的分发 Django的日常-2 路由层 我们之前已经接触过路由层,只是我们可能不知道他叫这个名字,实际上在Django里面路由层 ...

  4. Django( 学习第三部 Django的url路由层)

    目录 url路由层 路由匹配(有名分组与无名分组) 反向解析 路由分发 名称空间(了解) Django版本区别 url 路由匹配 注意事项: url方法,第一个参数是正则表达式,只要第一个参数能够匹配 ...

  5. Django学习——路由层之路由匹配、无名分组、有名分组、反向解析

    路由层之路由匹配 """路由你可以看成就是出去ip和port之后的地址""" url()方法 1.第一个参数其实是一个正则表达式 2.一旦第 ...

  6. Django 路由层(urlconf)

    Django 的路由层(URLconf) URL配置(conf)就像是Django所支撑的网站的目录; 本质就是:URL与调用该URL执行的视图函数的映射表; 通俗的讲:就是用户使用哪个url,URL ...

  7. Django 的路由层 视图层 模板层

    --------------------------------------------------------------通过苦难,走向欢乐.——贝多芬 Django-2的路由层(URLconf) ...

  8. Django路由层

    路由层简单配置 urlpatterns = [ url(r'^admin/$', admin.site.urls), url(r'^articles/2003/$', views.special_ca ...

  9. $Django 虚拟环境,2.0、1.0路由层区别,Httprequest对象,视图层(fbv,cbv),文件上传

    1 虚拟环境:解决问题同一台机器上可以运行不同版本的django,  1 用pychanrm创建--->files-->newproject--->选择虚拟环境  2 setting ...

随机推荐

  1. spring-boot-configuration-processor

    spring默认使用yml中的配置,但有时候要用传统的xml或properties配置,就需要使用spring-boot-configuration-processor了 引入pom依赖 <de ...

  2. linux下链接时缺少动态链接库

    1, 用ln将需要的so文件链接到/usr/lib或者/lib这两个默认的目录下边 ln -s /where/you/install/lib/*.so /usr/libsudo ldconfig 2, ...

  3. spark-sql性能优化之——动态实现多个列应用同一个函数

    在对一个dataframe的多个列实现应用同一个函数时,是否能动态的指定? 例如: 对A,B,C三列实现分组统计 1.初始化spark,构建DF val spark = SparkSession.bu ...

  4. Python骚操作(一)

    1. 交换变量值 2. 将列表中所有元素组合成字符串 3. 查找列表中频率最高的值 4. 检查连个字符串是不是由相同字母不同顺序组成 5. 反转字符串 6. 反转列表 7. 转置二维数组 8. 链式比 ...

  5. 2019-2020 ICPC, NERC, Northern Eurasia Finals

    A. Apprentice Learning Trajectory rdc乱编的做法 考虑贪心,每次会选择结束时间最早的. 设当前时间为 \(x\),那么可以区间有两类 a) \(l_i \leq x ...

  6. 客户端app支付宝登录接口

    如下内容: $url = 'apiname=com.alipay.account.auth&app_id=APP内容&app_name=mc&auth_type=AUTHACC ...

  7. java 自加和短路问题 几个例子

    x++可以看做一个独立的变量 如int a=x++;x的值先把他赋值给x++然后X++再赋值a,最后x再自加1 ++X   int a=++   X 先自加1 x的值赋值给++x然后++x再赋值a   ...

  8. agc38C LCMs

    https://atcoder.jp/contests/agc038/tasks/agc038_c 题意:给\(a_i\),求\(\sum_{i=1}^n\sum_{j=i+1}^nlcm(a_i,a ...

  9. Kubernetes的包管理工具Helm的安装和使用

    1.源码安装 [root@master ~]# wget https://storage.googleapis.com/kubernetes-helm/helm-v2.14.0-linux-amd64 ...

  10. 初识STL

    原生指针 泛型指针 智能指针 都是什么? iterator迭代器和指针的区别 C++标准模板库(STL)迭代器的原理与实现 [C++]STL常用容器总结之一:容器与迭代器 C++内置数组和array的 ...