django orm 中表与表之间建关系 视图层 路由层 django请求生命周期

django请求生命周期图:

django orm 中表与表之间建关系:
    1.一对多: ForeiqnKey(to='xxx')
    2.一对一: OneToOneField(to='xxxx')
    3.多对多: ManyToManyField(to='xxx')

    前面两个关键字会自动再字段后面加_id
    最后一个关键字 并不会产生实际字段 只是告诉django orm自动创建第三张表

视图层:
    1.三神装(HttpResponse,render,redirect)
        django视图函数必须给前端返回一个HttpResponse对象,否则报错

        相关:
            1.前后端分离(前端一人干(前端转成自定义对象),后端一个人干(python用字典))
            2.只要涉及到数据交互,一般情况下都是用json格式
            3.后端只负责产生接口(写接口文档,里面描述字典详细信息以及参数的传递),
              前端调用该接口拿到一个大字典;
              相关操作:
                    JSON.stringify()        json.dumps()
                    JSON.parse()            json.loads()
    
    2.JsonReponse
      1.后端往前端传字典时:当传递的数据中有汉字时,传给前端的是人不能识别字节码,
        1.data = {'name':'好帅哦 666','password':123}
          res = json.dumps(data,ensure_ascii=False)
          return HttpResponse(res)

        2.from django.http import JsonReponse
          data = {'name':'好帅哦 666','password':123}
          return JsonResponse(data,json_dumps_params={'ensure_ascii':False})

      2.后端往前端传列表时:需要将safe参数改为false
          l = [1,2,3,4,5,6,7,8]
          return JsonResponse(l,safe=False)  

    3.上传文件
        注意事项:
          前端:
            1.form表单中 enctype 要将默认的urlencoded 变成formdata
            2.form表单中 method  要将默认的 get 改为 post
          后端:
            1.学django初期要把settings中的中间建csrf注掉
            2.获取数据时用  request.FILES  来获取  (不用post)
        小结:request.的相关方法:
            1.request.method            查看数据提交方式
            2.request.GET               获取get请求的数据
            3.request.POST                获取post请求的数据
            4.request.FILES             获取文件内容
            5.request.path              只获取前端url的后缀,不要?后的参数
            6.request.get_full_fath()   后缀与参数全要
路由层:
    url()方法中  第一个参数是正则表达式,
      匹配规则:
           从上往下依次匹配,一旦前面的正则匹配到了内容,就不会继续往下匹配了,会直接执行对应的视图函数
        基于该特性,当项目庞大,url前后顺序没规划好,容易造成url错乱,找不到想要的页面    

        1.url(r'login', views.login),     模糊匹配,login前后无限制,可输入任意字符串,只要有login就能pipie到
        2.url(r'^login', views.login)     前面有限制,后面无,
        3.url(r'^login/$', views.login),  前后有限制,只有路径对了就可访问到
        4.url(r'^$', views.login),        网站首页路由配置
        5.url(r'',views.error)            网站错误路由配置
      注:1.django在路由的匹配的时候,当你在浏览器中没有敲最后的斜杠,
           django会先拿着你没有敲斜杠的结果取匹配 如果都没有匹配上,
           会让浏览器在末尾加斜杠再发一次请求 再匹配一次 如果还匹配不上才会报错;
         2.如果你想取消该机制 不想做二次匹配可以在settings配置文件中 指定
           APPEND_SLASH = False  # 该参数默认是True
    分组:        
        无名分组:路由匹配的时候,会将括号内的正则表达式匹配到的内容当做位置参数传递给视图函数
            url(r'^test/([0-9]{4})/', views.test)
            def test(request,xxx):
                print(xxx)
            注:views.test函数的参数除了request,还需要添加一个参数(名字随意),进行几次分组那么就需要多添加几次参数
        有名分组:路由匹配的时候,会将括号内的正则表达式匹配到的内容 当做关键字参数传递给视图函数
            url(r'^test/(?P<year>d+)/', views.test)  # ?p大写,在无名的分组的基础上加上了名字
            def test(request,year)
                print(year)
            注: 有名分组不能给函数传递随意的参数,是什么名,传什么参
        有名无名不能混合使用,但是同一种组内的话支持写多个(***)    
            无名分组支持多个: url(r'^test/(d+)/(d+)/', views.test),    
            有名分组支持多个: url(r'^test/(?P<year>d+)/(?P<xx>d+)/', views.test),
            
        

    反向解析:让链接根据正则表达式动态生成(模板中的超链接,视图中的重定向)
        本质:其实就是给你返回一个能够返回对应url的地址
        1.先给url和视图函数对应关系起别名
            url::(r'^index/&',views.index,name='kkk')
            注:同一个应用下,别名不能重复
        2.反向解析:
           后端反向解析:后端可以在任意位置通过reverse反向解析出对应的url
            from django.shortcuts import reverse
            reverse('kkk')            
           前端反向解析:{% url 'kkk' %}
           
        3.无名分组反向解析
            url:
                url(r'^index/(d+)/$',views.index,name='kkk')
            后端反向解析:
                reverse('kkk',args=(1,))  # 后面的数字通常都是数据的id值
            前端反向解析:
                {% url 'kkk' 1%}   # 后面的数字通常都是数据的id值
        
        4.有名分组反向解析:与无名相同
            url:
                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,statict文件夹,templates文件夹(********)
        应用:
             1.可以实现多人分组开发待完成后,只需要创建一个空的django项目,然后
             将多人开发的app全部注册进来,在总路由实现路由分发
             2.当你的应用下的视图函数特别特别多的时候,你可以建一个views文件夹,
               里面根据功能的细分再建不同的py文件(******)
        方法:项目名下urls.py(总路由)不再做路由与视图函数的匹配关系而是做路由的分发
        路由分发的两种方式:
            方式一:
                总路由:
                    # 不需要导入任何东西
                    url(r'^app01/',include('app01.urls')),
                    url(r'^app02/',include('app02.urls'))
                 app01路由:
                    在你创建app01的时候是app01下面是没有urls路由的需要自己手动创建,然后
                    把项目文件夹下的总路由copy到app01的路由下
                    urlpatterns = [
                        url(r'^index/', views.index),
                        ]
            方式二:
                总路由:
                    # 只需要导入include和app01与app02的urls并取别名
                     并且去别名
                    from django.conf.urls import url,include
                   from app01 import urls as a1
                   from app02 import urls as a2
                    url(r'^app01/',include(a1)),
                    url(r'^app02/',include(a2)),
                     app01路由:
                    在你创建app01的时候是app01下面是没有urls路由的需要自己手动创建,然后
                    把项目文件夹下的总路由copy到app01的路由下
                    urlpatterns = [
                        url(r'^index/', views.index),
                        ]

        
    名称空间:
        多个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:
            起别名时,别名不要重复,建议以应用名作为前缀
                name = 'app01_index'
                name = 'app02_index'
                
    伪静态:为了增加 搜索引擎(巨大的爬虫程序) seo查询力度,
        作用:提高你的网站被查询出来的概率
        静态网页:数据写死,不会变化的网页
        
    虚拟环境:为每个项目量身定做的解释器环境
        注:通常我们只会下载项目所需要的模块 不需要的一概不装
    django版本的区别:
        1.路由层方面 1.x 用 url, 2.x 用 path
        2.2.x 中的path 第一个参数 不再是正则表达式,是精总匹配
            注: 2.x中的 re_path 就是 1.x中的url,他们分组出来的数据都是字符串类型
        3.2.x中 path 提供的 五种默认转换器
            str,匹配除了路径分隔符(/)之外的非空字符串,这是默认的形式
            int,匹配正整数,包含0。
            slug,匹配字母、数字以及横杠、下划线组成的字符串。
            uuid,匹配格式化的uuid,如 075194d3-6885-417e-a8a8-6c931e272f00。
            path,匹配任何非空字符串,包含了路径分隔符(/)(不能用?)
        4.2.x中支持自定义转换器    
            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),  
                    ...  
                ]              
原文地址:https://www.cnblogs.com/wyf20190411-/p/11536742.html