orm表关系如何建立

​ 多对多

​ 一对多

​ 一对一

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

​ 一对多 外键字段建在 多的那一方

​ 多对多 多对多的外键关系需要建立在第三张表上来专门处理

​ 在models中导入模块from django.db import models

# Create your models here.
# 先不要考虑外键关系 先创基表
class Book(models.Model):
title = models.CharField(max_length=32)
# 小数总共八位 小数占两位
price = models.DecimalField(max_digits=8,decimal_places=2) # 书跟出版社是一对多 并且书是多的一方 所以外键字段健在书表中
publish_id = models.ForeignKey(to='Publish') # to用来指代跟哪张表有关系 默认关联的就是表的主键字段
"""
一对多外键字段 创建的时候 同步到数据中 表字段会自动加_id后缀 如果你自己加了_id 我orm头铁 再在后面加一个_id 所以你在写一对多外键字段的时候 不要自作聪明的加_id
""" # 书跟作者是多对多的关系 外键字段建在任意一方都可以 但是建议你建在查询频率较高的那一方
author = models.ManyToManyField(to='Author') # django orm会自动帮你创建书籍 和作者的第三张关系表
# author这个字段是一个虚拟字段 不能在表中展示出来 仅仅只是起到一个高速orm 建第三章表的关系的作用 class Publish(models.Model):
title = models.CharField(max_length=32)
email = models.EmailField() class Author(models.Model):
name = models.CharField(max_length=32)
age = models.IntegerField()
# 一对一的表关系 外键字段建在任意一方都可以 但是建议你建在查询频率较高的那一方 author_detail = models.OneToOneField(to='Author_detail') # fk + unique
"""
一对一外键字段 创建的时候 同步到数据中 表字段会自动加_id后缀 如果你自己加了_id 我orm头铁 再在后面加一个_id 所以你在写一对一外键字段的时候 不要自作聪明的加_id
""" class Author_detail(models.Model):
phone = models.BigIntegerField()
addr = models.CharField(max_length=32)

django中间件

反代理中间件

语言环境中间件

消息中间件

会话中间件

保护中间件

交易中间件

自定义的中间件必须继承MiddlewareMixin

访问index之前需要登录,logout退出登录返回login,采用中间件

中间件注册在settings中的MIDDLEWARE列表中

路由层

urls.py 路由层

url第一个参数是正则表达式 只要该正则表达式能够匹配到的内容

就会立刻执行后面的视图函数 而不再往下继续匹配了

路由匹配

取消django自动让浏览器加斜杠的功能
APPEND_SLASH = False  # 该参数默认是
Truefrom app01 import views urlpatterns = [
url(r'^admin/', admin.site.urls), # url第一个参数是一个正则表达式
url(r'^test/$', views.test), # 一旦正则表达式能够匹配到内容 会立刻结束匹配关系 直接执行后面对应的函数
在后面加上$前面加上^必须输入这两个符号内的数据,输入其他的数据会报错
url(r'^testadd/$', views.testadd),
] url(r'^test/[0-9]{4}', views.test),必须在test/后面跟上四位0-9之间的数字,才能显示
url(r'^test/([0-9]{4})/', views.test),用()包裹住[0-9]{4},运行会报错:test() takes 1 positional argument but 2 were given,
翻译:test()有一个位置参数,但给出了两个,然后在运行框下面删除run内容,在views中request后面添加xxx,然后打印print('多余的参数',xxx),再次运行就可以正常显示了,在运行框会返回多余的参数1234

django匹配路由的规律

不加斜杠 先匹配一次试试 如果匹配不上 会让浏览器从定向 加上一个斜杠 再来一次 如果还是匹配不上 才会报错

路由匹配值匹配url部分

不匹配?后面的get携带的参数

无名分组

无名分组
url(r'^test/(\d+)/',views.test)
test() takes 1 positional argument but 2 were given
会将括号内匹配到的内容当做 位置参数 传递给后面的视图函数test(request,args) 当你的路由中有分组的正则表达式 那么在匹配到的内容
执行视图函数的时候 会将分组内正则表达式匹配到的内容当做位置参数传递给视图函数
test(request,分组内正则表达式匹配到的内容)

有名分组

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

url(r'^testadd/(?P<year>\d+)/', views.testadd),
testadd() got an unexpected keyword argument 'year' 当你的路由中有分组并且分组起了别名 那么在匹配内容的时候
会将分组内的正则表达式匹配到的内容当做关键字参数传递给视图函数
testadd(request,year=分组内的正则表达式匹配到的内容) 利用有名无名分组 我们就可以在调用视图函数之前给函数传递额外的参数
注意:有名和无名分组不能混合使用
在用一种分组的情况下可以有多个

反向解析

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

  1. 第一种情况

    路由中没有正则表达式 直接是写死的

    url(r'^home/', views.home,name='xxx'),
    # 给路由与视图函数对应关系起别名 前端反向解析
    {% url 'xxx' %} 后端反向解析
    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}) # 了解即可 例子:
    以编辑功能为例
    url(r'^edit_user/(\d+)/',views.edit_user,name='edit') def edit_user(request,edit_id):
    # edit_id就是用户想要编辑数据主键值
    pass {% 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

小组长只需要将所有人开发的app整合到一起即可完成一个大项目的拼接

路由分就是解决项目的总路由匹配关系过多的情况

使用路由分发 会将总路由不再做匹配的活 而仅仅是做任务分发(请求来了之后 总路由不做对应的关系,只询问你要询问哪个app的功能 然后将请求转发给对应的app去处理)

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)),
]
子路由
from django.conf.urls import url
from app01 import views urlpatterns = [
url('^reg/',views.reg)
] from django.conf.urls import url
from app02 import views urlpatterns = [
url('^reg/',views.reg)
] 最省事的写法
url(r'^app01/',include('app01.urls')),
url(r'^app02/',include('app02.urls')),

名称空间

当多个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> 其实上面的名称空间知识可以完全不用 你只需要保证起别名的时候 在整个django项目中不冲突即可
可以定义参考的文献
起别名的时候统一加上应用名前缀
urlpatterns = [
url(r'^reg/',views.reg,name='app02_reg')
] urlpatterns = [
url('^reg/',views.reg,name='app01_reg')
]

伪静态

将一个动态网页伪装成一个静态的网页(在网址的最后面加上.html) 以此来提高搜索引擎SEO查询频率和收藏的力度

所谓的收藏引擎其实就是一个特别巨大的爬虫程序,把你输入的关键字,搜索展示出来对应的内容

虚拟环境

给每一个项目 装备该项目所需要的模块 不需要的模块一概不装

每创建一个虚拟环境就类似于你重新下载了一个纯净的python解释器

之后该项目用到里面的什么模块 你就装什么(虚拟环境一台机器上可以有N多个)

不要在你的机器上限制创建虚拟环境

django版本的区别

django1.X  django2.X
urls.py 中路由匹配的方法有区别 django2.X用的是path
urlpatterns = [
path('admin/', admin.site.urls),
]
django1.X用的是url
urlpatterns = [
url(r'^reg.html',views.reg,name='app02_reg')
] # 区别django2.X里面path第一个参数不是正则也不支持正则 写什么就匹配什么
虽然path不支持正则 感觉也好用 django2.X还有一个re_path的方法 该方法就是你django1.X里面的url
虽然path支持 但是它提供了五种转换器 能够将匹配到的数据自动转换成对应你的数据类型转换器 str 匹配除了路径分隔符(/) 之外的非空字符串,这是默认的形式
int 匹配正数,包含0
slug 匹配字母、数字以及横杠、下换线组成的字符串
uuid 匹配格式化的uuid,为防止多个URL映射到同一个页面,必须包含破折号并且字母必须小写,如458464d45-4546e-464d585c。返回一个UUID实例。
path 匹配任何非空字符串,包含了路径分隔符(/)(不能用?)。这样就可以与完整的URL路径进行匹配,而不仅仅是与URL路径的一部分进行匹配str。 除了有默认五种转换器之外 还支持自定义转换器
转换器是一个类或接口,它的要求有三点:
regex:类的属性,字符串类型
to_python(self,value)方法,value是由类属性regex所匹配到的字符串,返回具体的python变量值,以供django传递到对应的视图函数中
to_url(self,value)方法,和to_python相反,value是一个具体的python变量值,返回其字符串,通常用于url反向引用

视图层

form表单上传文件 后端如何获取文件

form表达文件需要注意的事项

  1. method必须改成post
  2. enctype改成formdata格式

前期你在使用post朝后端发送请求的时候 需要去settings配置文件中注释掉一个中间件csrf

最新文章

  1. Python Quick list dir
  2. FreeBSD 10 中文环境
  3. ELK-Python(二)
  4. PHP超级全局变量——Session 变量
  5. noip知识点总结之--线性筛法及其拓展
  6. 转: 理解Python的With语句
  7. Mysql常见报错解决方法
  8. Xcode升级导致插件失效的解决办法-b
  9. windows程序设计读书笔记1——创建窗口
  10. openfire研究之部署连接管理器(connection manager)
  11. Trie三兄弟——标准Trie、压缩Trie、后缀Trie
  12. 【iOS7一些总结】9、与列表显示(在):列表显示UITableView
  13. android自定义控件(理论知识学习 +自定义属性的讲解)
  14. 运行第一个Go Web框架
  15. 麒麟子Cocos Creator实用技巧
  16. dubbo源码之服务消费
  17. nginx的proxy_pass路径转发规则最后带/问题
  18. text2
  19. Codeforces Round #423 (Div. 2, rated, based on VK Cup Finals) Problem D (Codeforces 828D) - 贪心
  20. p值还是 FDR ?

热门文章

  1. swiper 插件里面嵌套可滚动内容
  2. Javascript简单算法
  3. php curl的隐藏BUG
  4. CentOS源码安装Wireshark
  5. 转: Linux题目
  6. java最大余数法(百分比算法Echarts)
  7. Vue:$route 和 $router 的区别
  8. Mybatis的插件 PageHelper 分页查询使用方法
  9. https://blog.csdn.net/u012235003/article/details/54576737
  10. 转:步步LINUX C--进程间通信(二)信号