一。数据库的关系建立。

  在原生的数据库语句中,建立表与表之间的联系,就是添加一个字段,将联系的表的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数据库表关联,路由和视图的更多相关文章

  1. Django基础三之路由、视图、模板

    Django基础三之路由.视图.模板 目录 Django基础三之路由.视图.模板 1. Django 请求和返回周期 1.1 路由层之路由匹配 1.2 有名分组 1.3 无名分组 2. 反射解析 3. ...

  2. 六、Django之表单和类视图-Part 4

    一.表单form 为了接收用户的投票选择,我们需要在前端页面显示一个投票界面.让我们重写先前的polls/detail.html文件,代码如下: <h1>{{ question.quest ...

  3. mysql数据库左联的使用(一张数据库表关联到另外一张数据库表)

    左联的数据库表,然后显示的在页面显示的jsp里面改一下代理种类ID的name,这样在页面上显示的不是id了,而是变成你修改了以后相对于的name了

  4. Django数据库表的关联问题

    Django模型中,比较难以理解的要数表和表之间相关联的部分,下面主要说说外键-ForeignKey和ManyToManyField2个字段类型. 我们知道ForeignKey说的是“一对多”,那么问 ...

  5. Sql语句导出数据库表结构及查询表视图储存过程名

    --一句Sql把表结构全部查询出来 SELECT 表名 = Case When A.colorder=1 Then D.name Else '' End, 表说明 = Case When A.colo ...

  6. Django数据库表初始化缓存清除

    新建的django项目中没有应用app01??? models中也没有UserInfo表???? 但在migrate是却一直报错!!!!! 产生此种现象的原因: 之前的项目中肯定是用到过应用app01 ...

  7. Django 08 Django模型基础3(关系表的数据操作、表关联对象的访问、多表查询、聚合、分组、F、Q查询)

    Django 08 Django模型基础3(关系表的数据操作.表关联对象的访问.多表查询.聚合.分组.F.Q查询) 一.关系表的数据操作 #为了能方便学习,我们进入项目的idle中去执行我们的操作,通 ...

  8. 使用LitePal建立表关联

    关联关系的基础知识   喜欢把所有的代码都写在一个类里的程序员肯定是个新手.没错,任何一个像样的程序都不可能仅仅只有一个类的,同样地,任何一个像样的数据库也不可能仅仅只有一张表.我们都知道,在面向对象 ...

  9. 项目那几步走:先配置setting路径文件、创建数据库、执行数据库迁移命令、配置mysql数据库信息、注册app、注释中间件、pymysql替换mysqldb-配置urls路由-继续视图函数-然后HTML页面展示-HTML里面导入css文件、models配置数据库表、

    django使用mysql数据库: 首先cmd创建库 1.settings: """Django settings for day42 project. Generate ...

随机推荐

  1. 公司员工表示 nginx 之父被警方带走

    ZDNet 12 日报导,俄罗斯警方当天突击搜查了 NGINX 公司(nginx 服务器项目商业化公司)在莫斯科的办事处,并带走了 NGINX 公司联合创始人 Igor Sysoev 与 Maxim ...

  2. 201871010126 王亚涛《面向对象程序设计 JAVA》 第十三周学习总结

      内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 https://www.cnblogs.com/nwnu-daizh/p/ ...

  3. 【HDU4947】GCD Array(莫比乌斯反演+树状数组)

    点此看题面 大致题意: 一个长度为\(n\)的数组,实现两种操作:将满足\(gcd(i,k)=d\)的\(a_i\)加上\(v\),询问\(\sum_{i=1}^xa_i\). 对于修改操作的推式子 ...

  4. BoW算法及DBoW2库简介(二)

    一.BoW算法 用OpenCV实现了最简单的BoW算法进行了一次小规模的图像检索任务,使用UKbench数据库,算法原理和网上的描述差不多,使用K-means算法进行聚类,这里使用KDTree算法进行 ...

  5. Linux 安装 MySQL 出现 Could NOT find Curses

    通过源码安装 MySQL 数据库,下载了 mysql-5.5.24 的版本,在使用 cmake 时产生了报错,如下: CMake Error at cmake/readline.cmake: (MES ...

  6. pixijs shader fade 从左到有右淡入 从下到上淡入效果

    pixijs shader fade 从左到有右淡入     从下到上淡入效果 const app = new PIXI.Application({ transparent: true }); doc ...

  7. 一些常见的http状态码

    HTTP状态码是服务器和客户端之间交流信息的语言,下面列出一些常见的HTTP状态码. 1XX系列 指定客户端应相应的某些动作,代表请求已被接受,需要继续处理.由于在HTTP/1.0协议中没有定义任何1 ...

  8. javascript实现base64编码、解码

    我们知道,浏览器的window对象提供有window.atob()和window.btoa()方法可以对字符串进行Base64编码和解码. console.log(window.btoa(window ...

  9. java 连缀用法

    连缀用法,即是在实例化对象时,同时为对象的属性设值. 如示例所示,在创建对象时,同时调用属性的设值函数,为属性赋值 Apple apple = new Apple() .setColor(" ...

  10. sql server pivot

    SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE TABLE [dbo].[YearSalary]( [year] [int] NULL, ...