目录css
orm表关系如何创建
多对多
一对多
一对一
换位思考 先站在一张表上面分析 而后再站在另外一张分析html
一对多 外键字段建在 多的那一方 多对多 多对多的外键关系须要创建第三章来专门处理 图书表 出版社表 做者表
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路由匹配规律:不加斜杠,先匹配一次,若是匹配不上,会让浏览器重定向,加一个斜杠再匹配一次前端
url第一个参数是一个正则表达式 只要该正则表达式可以匹配到内容,就会马上执行后面的视图函数 而再也不往下继续匹配了。python
# settings配置文件中加上: # 取消django自动让浏览器增长斜杠 APPEND_SLASH = False # 该参数默认是True ''' 加上这句话,浏览器端若是后缀不加斜杠就会自动报错,后端不在自动加斜杠让浏览器再请求一次 '''
urlpatterns = [ url(r'^admin/', admin.site.urls) , # url第一个参数是一个正则表达式 url(r'^test/$', views.test), # 一旦正则表达式可以匹配到内容 会马上结束匹配关系 直接执行后面对应的函数 url(r'testddd/$', views.testddd), ] # django匹配路由的规律 # 不加斜杠 先匹配一次试试 若是匹配不上 会让浏览器重定向 加一个斜杠再来一次 若是还匹配不上 才会报错 """ 路由匹配值匹配url部分 不匹配?后面的get携带的参数 """
无名分组:将分组内正则表达式匹配到的内容当作位置参数传递给视图函数 url(r'^test/([0-9]{4})/', views.test) url(r'^test/(\d+)/', views.test), # 匹配一个或者多个数字 test() takes 1 positional argument but 2 were given # 当你的路由中有分组的正则表达式 那么在匹配到内容 # 执行视图函数的时候 会将分组内正则表达式匹配到的内容当作位置参数传递给视图函数 test(request,分组内正则表达式匹配到的内容)
有名分组(将加括号的正则表达式匹配到的内容当作关键字参数自动传递给对应的视图函数) url(r'^test/(?P<year>\d+)/',views.test), #将匹配到的数字起别名,叫year,做为关键字参数传给视图函数 def test(request,year): print(year) return HttpResponse('test') 注意:无名分组和有名分组不能混着用!!! url(r'^test/(\d+)/(?P<year>\d+)/',views.test)
# 可是支持用一类型多个形式匹配 # 无名分组多个 url(r'^test/(\d+)/(\d+)/',views.test), # 有名分组多个 url(r'^test/(?P<year>\d+)/(?P<xxx>\d+)/',views.test),
第一种状况:jquery
""" 根据一个别名 动态解析出一个结果 该结果能够直接访问对应的url """ # 路由中没有正则表达式 直接是写死的 url(r'^home/', views.home,name='xxx'), # 给路由与视图函数对应关系起别名 # 前端反向解析 {% url 'xxx' %} # 后端反向解析 from django.shortcuts import render,HttpResponse,redirect,reverse url = reverse('xxx')
第二种状况:git
无名分组的反向解析 在解析的时候 你须要手动指定正则匹配的内容是什么 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,)) # 手动传入的参数 只须要知足可以被正则表达式匹配到便可
第三种状况正则表达式
''' 有名分组的反向解析 在解析的时候 你须要手动指定正则匹配的内容是什么 有名分组的反向解析能够跟无名分组同样 ''' 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整合到一个空的django项目里面,而后在settings配置文件注册 再利用路由分发将多个app整合到一块儿便可完成大项目的拼接,路由分发解决的就是项目的总路由匹配关系过多的状况,使用路由分发 会将总路由再也不作匹配的活 而仅仅是作任务分发(请求来了以后 总路由不作对应关系,只询问你要访问哪一个app的功能 而后将请求转发给对应的app去处理)。django
# 第一种分发方式: # settings中的总路由 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)), ] # app01的settings中的子路由 from django.conf.urls import url from app01 import views urlpatterns = [ url('^reg/',views.reg) ] # app02的settings中的子路由 # app02是刚刚建立的的,要在总路由的INSTALLED_APPS中注册 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建立一个名称空间,而后在反向解析的时候 能够选择到底去哪一个名称空间中查找别名。bootstrap
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') ]
将一个动态网页假装成一个静态网页 以此来提升搜索引擎SEO查询频率和搜藏力度
所谓的搜索引擎其实就是一个也别巨大的爬虫程序后端
给每个项目 装备该项目所须要的模块 不须要的模块一律不装 每建立一个虚拟环境就相似于你从新下载了一个纯净python解释器 以后该项目用到上面 你就装什么(虚拟环境一台机器上能够有N多个) 不要在你的机器上无限制建立虚拟环境
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支持 可是它提供了五种转换器 可以将匹配到的数据自动转换成对应的类型 # 除了有默认五种转换器以外 还支持你自定义转换器
form表单上传文件 后端如何获取文件 form表达传文件须要注意的事项 1.method必须改为post 2.enctype该成formdata格式 前期你在使用post朝后端发请求的时候 须要去settings配置文件中注释掉一个中间件csrf
#urls.py文件 urlpatterns = [ url('^reg/',views.reg,name='reg'), url('^upload_file/',views.upload_file), ] # upload_file.py文件 def upload_file(request): if request.method=='POST': print(request.POST) # <QueryDict: {}> print(request.FILES) # django会将文件类型的数据放到request.files里面 # <MultiValueDict: {'myfile': [<InMemoryUploadedFile: aaa.xls (application/vnd.ms-excel)>]}> file_obj = request.FILES.get('myfile') print(file_obj) # aaa.xls print(file_obj.name) # aaa.xls with open(file_obj.name,'wb') as f: for line in file_obj: f.write(line) ''' django针对不一样得数据类型,会帮你解析并放到不一样得方法中供你调用 ''' return render(request,'upload_file.html')
<!--upload_file.html文件--> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> <link rel="stylesheet" href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css"> <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script> </head> <body> <form action="" method="post" enctype="multipart/form-data"> <input type="file" name="myfile"> <input type="submit"> </form> </body> </html>