day53_9_17 django数据库表关联,路由和视图
一。数据库的关系建立。
在原生的数据库语句中,建立表与表之间的联系,就是添加一个字段,将联系的表的id值添加到该字段中。
django所作的也就是这些。
以图书管理系统为例,图书管理系统有四张表:书籍表,作者表,出版社表,书籍细节表。他们之间的对应关系如下:
书籍对应书籍细节表是一对一。
书籍对应作者表是多对多。
出版社对应书籍表是一对多。
这些在django都有相关的字段或者虚拟字段来建立。
1。建立一对多的关系。
对于一对多的字段需要将其添加到多的那张表中,也就是书籍表:
class Book(models.Model):
title = models.CharField(max_length=64)
price=models.DecimalField(max_digits=8,decimal_places=2)
publish = models.ForeignKey(to='Publish')
authors = models.ManyToManyField(to='Author')
其中关键字ForeignKey,外键,就默认将PUblish中的数据的id添加到外键中。
其中外键也可以这样写:
publish = models.ForeignKey(to=Publish)
直接将对象作为参数传入,但是需要将该参数写在上面,因为解释器是从上往下编译。
补充:max_digits是指整数位的显示位数,decimal_places是小数位显示的个数。
2.多对多。
多对多的情况只需要在两表中的一个建立ManyToManyField即可,建立的不是真正的字段,是一个虚拟的。会重新建一个表表示两者的对于关系。
3.一对一。
一对一的关系体现在书籍和书籍详情上,可以使用关键字:OneToOneField字段进行绑定,一般绑定在查询频率较高的表中。
class Author(models.Model):
name = models.CharField(max_length=32)
age = models.IntegerField()
author_detail = models.OneToOneField(to='AuthorDetail',null=True)
在foreignkey中,字段后面会自动添加_id作为区分。无论你原来有没有。
二。django的生命周期。
一般的,从前端的请求发送都会发送到wsgiref模块进行处理,然后从路由urls中寻找相应视图函数,最后通过模板和数据库的渲染,返回到页面。
三。路由匹配。
当前端发送数据请求时通常携带请求信息等,其中就包括路,路由决定了后端提交给前端的模板,通过路由可以搜寻到相关的视图函数。
在django中,路由匹配通常是url开头的以正则表达式为基础的匹配。
当正则表达式匹配上路由时,就不会往下继续匹配。
1.加斜杠二次匹配。
当在浏览器中没有加斜杠就进行匹配而没能匹配到结果时,会自动加上/再次进行匹配。如果没有比配到就会报错。
如果需要取消这一机制,需要在settings配置文件:
APPEND_SLASH = False # 该参数默认是True
通常,如果需要精准匹配路由,都会在首和尾添加符号^$。
2,^$应用。
我们可以通过正则表达式^$来匹配初始页面,用来渲染该项目的初始页面。
3.''空应用。
在匹配的最后可以加上空字节匹配所有路由,当第一次匹配,没有任何结果时就返回错误页面渲染,但是这样就不能使用第一条的二次匹配了。
四。有名分组与无名分组。
在url路由匹配时,由于匹配的性质时正则表达式,所以,可以在正则表达式中书写分组。
复习:在正则表达式中,出现了分组时()findall就会事先展示分组中的内容。
无名分组。
而在这里,分组匹配的内容会作为位置参数传给它的视图函数,所以,视图函数中需要指定一个位置参数来接受该值。
def test(request,xx,year):
print(year)
print(xx)
return HttpResponse('test') url(r'^test/([0-9]{4})/', views.test)
有名分组:
当正则表表达式给分组中匹配的值起了别名后,就会像视图传入一个关键字参数,所以后端需要传入相应的名字的参数作为接受。
url(r'^test/(?P<year>\d+)/', views.test)
注意:无名分组和有名分组不能混合使用,即不能出现以下情况:
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的地址给后端,所以需要匹配正则。
反向解析可以让后端和前端动态的拿到url。
首先需要对对应的url起别名。:
url(r'^index/$',views.index,name='kkk')
1.前端反向解析:
通过以下函数可以在前端拿到对应 的url:
{% url 'kkk' %}
2.后端反向解析:
from django.shortcuts import
render,HttpResponse,redirect,reverse
reverse('kkk')
注意,这个函数是根据别名拿对应的url即使不是本函数的url也可以拿到!
3.无名分组反向解析。
当url中出现正则表达式有分组的出现,其需要匹配一定的数值才能拿到该url,具体如下。
url(r'^index/(\d+)/$',views.index,name='kkk')
直接通过kkk是不能获取对应的url的,需要添加一定的参数:
后端反向解析
reverse('kkk',args=(1,)) # 后面的数字通常都是数据的id值
前端反向解析
{% url 'kkk' 1%} # 后面的数字通常都是数据的id值
一般的,后端反向解析都是用来跳转页面用的,前端都是用来传递关键信息(猜测)。
4。有名分组反向解析。
当有名分组时,需要反向解析其实和无名可以公用一个方法:
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项目特别庞大的时候 路由与视图函数对应关系特别特别多,那么你的总路由urls.py代码太过冗长 不易维护。
每一个应用都可以有自己的urls.py,static文件夹,templates文件夹。所以在app中创建这些文件即可。
项目下的urls只需要分发路由即可:
from app01 import urls as app01_urls
from app02 import urls as app02_urls
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^app01/',include(app01_urls)),
url(r'^app02/', include(app02_urls))
]
在项目中再调用相应的函数执行:
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^index/', views.index),
]
当然,django支持简写,也就是导入模块,直接以字符串代替模块名
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^app01/',include('app01.urls')),
url(r'^app02/',include('app02.urls')), ]
总路由中 一级路由的后面千万不加$符号
七。名称空间。
在多个app中,如果多个路由起了相同的别名,在视图进行反向解析是,会是哪个呢。
答案是只能返回最后一个app中的那个别名对应的路由。
解决方法1:
在路由分发时,给其定义一个名称空间,在解析时,加上名称空间即可区分:
总路由
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' %}
解决方法2:
在其名字时不要冲突即可,在起别名时通常将app名字加在前面:
name = 'app01_index'
name = 'app02_index'
八。伪静态。
静态网页:数据是写死的 万年不变。
伪静态网页的设计是为了增加百度等搜索引擎seo查询力度。
所有的搜索引擎其实都是一个巨大的爬虫程序。
这是一个网站优化相关的知识,通过伪静态确实可以提高你的网站被查询出来的概率,但是再怎么优化也抵不过RMB玩家。
该方法就是在网站后面加(.html)
九。虚拟环境。
一般情况下,每一个项目都会配置本地环境给它,就是装载,相同的模块,就是本地环境。
而每一个项目需要不同的环境运行时,就需要虚拟环境为每个项目配置不同 的环境。
在虚拟环境创建时,会重新下载一个全新的解释器。
十。Django1.x和2.x的区别
路由区别:
路由层1.X用的是url,而2.X用的是path。
2.X中的path第一个参数不再是正则表达式,而是写什么就匹配什么 是精准匹配。
在2.x中也有re_path与url的使用方式一样。
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,匹配任何非空字符串,包含了路径分隔符(/)(不能用?)
用法:
path('index/<int:id>/',index) # 会将id匹配到的内容自动转换成整型
其中id可以传到后端去。
path还支持自定义的转化器:
class FourDigitYearConverter:
regex = '[0-9]{4}'
def to_python(self, value):
return int(value)
def to_url(self, value):
return '%04d' % value 占四位,不够用0填满,超了则就按超了的位数来!
register_converter(FourDigitYearConverter, 'yyyy')
urlpatterns = [
path('articles/2003/', views.special_case_2003),
path('articles/<yyyy:year>/', views.year_archive),
...
]
十一。视图层。
1,视图层三个常用的函数:
1.HttpResponse
2.render
3.redirect
django视图函数必须要给返回一个HttpResponse对象。因为其他的方法内部都是返回的HttpResponse。
2.JsonReponse。
JsonReponse函数主要是返回一个json后的对象给前端,需要使用这个函数。
from django.http import JsonResponse
def index(request):
data = {'name':'名字','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即可
这个等同于使用json模块转换后使用httpresponse传输。
其中,如果需要传输的数据中有中文,在json中需要加关键字参数:ensure_ascii=False。
在这个模块需要将这个字段作为字典传入,内部会自动解析:
JsonResponse(data,json_dumps_params= {'ensure_ascii':False})
如果要传字典以外的参数,需要将safe参数设置为false。
一般的,在开发者模式中,有前后端分离的开发者模式,需要后端将参数作为字典传给前端供其处理。
补充:
前端处理json数据:
JSON.stringify() json.dumps()
JSON.parse() json.loads()
3.上传文件。
在上传文件时,有些事项需要注意:
1.enctype需要由默认的urlencoded变成formdata。
2.method需要由默认的get变成post。
在后端获取文件时,并不是在POST中获取文件,而是在request.FILES中获取文件。
def down(request):
if request.method == 'POST':
file_obj = request.FILES.get('my_file')
with open(file_obj.name,'wb') as f:
for i in file_obj.chunks():
f.write(i)
return HttpResponse('收到了')
return render(request,'down_load.html')
其中chunks()是将其变成可迭代对象,file也是一个可迭代对象,所以可以不加。
FILES中取值方式和GET中一样,取出列表中的最后一个。
其他request中的参数(部分):
request.method #判断get post
request.GET
request.POST
request.FILES
request.path # 只回去url后缀 不获取?后面的参数
request.get_full_path() # 后缀和参数全部获取
request.body #原生的二进制数据
RBAC(role based access control)
基于角色的权限管理。
需要对用户访问的路由进行限制。
day53_9_17 django数据库表关联,路由和视图的更多相关文章
- Django基础三之路由、视图、模板
Django基础三之路由.视图.模板 目录 Django基础三之路由.视图.模板 1. Django 请求和返回周期 1.1 路由层之路由匹配 1.2 有名分组 1.3 无名分组 2. 反射解析 3. ...
- 六、Django之表单和类视图-Part 4
一.表单form 为了接收用户的投票选择,我们需要在前端页面显示一个投票界面.让我们重写先前的polls/detail.html文件,代码如下: <h1>{{ question.quest ...
- mysql数据库左联的使用(一张数据库表关联到另外一张数据库表)
左联的数据库表,然后显示的在页面显示的jsp里面改一下代理种类ID的name,这样在页面上显示的不是id了,而是变成你修改了以后相对于的name了
- Django数据库表的关联问题
Django模型中,比较难以理解的要数表和表之间相关联的部分,下面主要说说外键-ForeignKey和ManyToManyField2个字段类型. 我们知道ForeignKey说的是“一对多”,那么问 ...
- Sql语句导出数据库表结构及查询表视图储存过程名
--一句Sql把表结构全部查询出来 SELECT 表名 = Case When A.colorder=1 Then D.name Else '' End, 表说明 = Case When A.colo ...
- Django数据库表初始化缓存清除
新建的django项目中没有应用app01??? models中也没有UserInfo表???? 但在migrate是却一直报错!!!!! 产生此种现象的原因: 之前的项目中肯定是用到过应用app01 ...
- Django 08 Django模型基础3(关系表的数据操作、表关联对象的访问、多表查询、聚合、分组、F、Q查询)
Django 08 Django模型基础3(关系表的数据操作.表关联对象的访问.多表查询.聚合.分组.F.Q查询) 一.关系表的数据操作 #为了能方便学习,我们进入项目的idle中去执行我们的操作,通 ...
- 使用LitePal建立表关联
关联关系的基础知识 喜欢把所有的代码都写在一个类里的程序员肯定是个新手.没错,任何一个像样的程序都不可能仅仅只有一个类的,同样地,任何一个像样的数据库也不可能仅仅只有一张表.我们都知道,在面向对象 ...
- 项目那几步走:先配置setting路径文件、创建数据库、执行数据库迁移命令、配置mysql数据库信息、注册app、注释中间件、pymysql替换mysqldb-配置urls路由-继续视图函数-然后HTML页面展示-HTML里面导入css文件、models配置数据库表、
django使用mysql数据库: 首先cmd创建库 1.settings: """Django settings for day42 project. Generate ...
随机推荐
- 运行springboot项目报错:Field userMapper in XX required a bean of type 'xx' that could not be found.
运行springboot项目报错: *************************** APPLICATION FAILED TO START ************************** ...
- idea延长使用期
0. 如果你的idea(版本2019.02)是已过期状态则先上网找个激活码激活再进行下面步骤延长使用期至2089年 1. 附件下载地址: 链接:https://pan.baidu.com/s/1L5O ...
- 8. Vue - Router
一.Vue Router 的使用 JavaScript: 1.创建组件:创建单页面应用需要渲染的组件 2.创建路由:创建VueRouter实例 3.映射路由:调用VueRouter实例的map方法 4 ...
- Paper | Highway Networks
目录 1. 网络结构 2. 分析 解决的问题:在当时,人们认为 提高深度 是 提高精度 的法宝.但是网络训练也变得很困难.本文旨在解决深度网络训练难的问题,本质是解决梯度问题. 提出的网络:本文提出的 ...
- Jenkins操作学习 -- 配置及使用
一.jenkins基本配置 1.在Jenkins首页,点击Manage Jenkins,然后再点击Manage Plugins插件管理,安装必要的插件.这里我只需要安装Git,因为第一次初始化安装没成 ...
- Protractor-引入Cucumber
上一篇博文中我们已经在package.json中写入了cucumber依赖库,在执行 npm install 之后,cucumber就已经下载好了.接下来要做的是修改conf.js,请参考下图: 去年 ...
- Linux中Swap与Memory内存简单介绍
1.背景介绍 这篇文章介绍一下Linux中swap与memory.对于memory没什么可说的就是机器的物理内存,读写速度低于cpu一个量级,但是高于磁盘不止一个量级.所以,程序和数据如果在内存的 ...
- MongoDB for OPS 01:服务介绍与基本使用
写在前面的话 数据库产品已经学习了两个,MySQL 和 Redis.接下来开始研究另外一款 NoSQL 产品 MongoDB,注意跟芒果没啥关系.该产品对于运维来说,相对于操作少一些. 关于 Mong ...
- efcore dotnet cli add-migrations update-database
add-migrations update-database 如何通过dotnet cli调用 dotnet tool install --global dotnet-ef dotnet ef mig ...
- ASP.NET(1)
1.IIS安装问题,先装VS再装IIS,处理程序映射有问题,使用VS自带的控制台输入命令,注册路径 2.开发模式,一般处理程序,使用IO操作读取html文件,使前后端分离 3.post请求和get请求 ...