Django路由与视图

路由层

一.路由匹配规则:

第一个参数是正则表达式,匹配规则按照从上往下一次匹配,匹配到一个以后当即匹配,直接执行对应的视图函数html

url(r'login', views.login),

若是按上面的形式匹配的话就成模糊匹配了,login的前面没有限制条件,能够输入任意的字符串,login的后面也没有限制条件也是能够输入任意的字符串,这样的话致使只要我路径里面有login这样的关键字不管我输入什么都没有关系,均可以访问的到,怎么解决方式是在前面加^h和后面加$符号,这样的话就限制了,只要能是路径对了才能访问到,以下。前端

url(r'^login/$', views.login),  #而后去写对应的视图函数就能够了

网站首页路由配置:python

url(r'^$', views.login),  #而后去写对应的视图函数就能够了

网页错误路由设置:git

url(r'',views.error)  #而后去写对应的视图函数就能够了

二.有名分组和无名分组传参

无名分组(将加括号的正则表达式匹配到的内容当作位置参数自动传递给对应的视图函数)

路由层正则表达式

url(r'^login/([0-9]{4})$', views.login),  # ([0-9]{4})匹配4个数字而后进行分组

视图函数层django

def login(request,year): # 若是分了一个组的话必定要的对应的视图函数加上一个函数,若是有两个就加上两个参数
    print(year) # http://127.0.0.1:8000/login/2019  打印结果就是2019
    return render(request,'login.html')

多个无名分组

路由层后端

url(r'^login/([0-9]{4})([0-9]{2})$', views.login), # ([0-9]{4})匹配4个数字而后进行分组  ([0-9]{2}) 匹配2个数字而后进行分组

视图函数层:app

def login(request,*args): # 若是分了一个组的话必定要的对应的视图函数加上一个函数,若是有两个就加上两个参数
    print(agrs) # http://127.0.0.1:8000/login/2019/06  打印结果就是(2019,06)
    return render(request,'login.html')

有名分组:

有名分组(将加括号的正则表达式匹配到的内容当作关键字参数自动传递给对应的视图函数)函数

​ 注意:无名分组和有名分组不能混着用!!!post

路由层:

url(r'^index/(?P<year>\d+)/',views.index)

视图函数层方式一:

def index(request,year):
        print(year)
        return HttpResponse('test')

视图函数层方式二

def index(request,**kwargs):
        print(kwargs)
        return HttpResponse('test')

反向解析

根据名字动态获取对应的路径

前端模板方式

语法 {% url '路由的别名' %}

路由层:

url(r'^index111/', views.index,name='xxx'),
    # 能够给每个路由与视图函数对应关系起一个名字
    # 这个名字可以惟一标识出对应的路径
    # 注意这个名字不能重复是惟一的

前端模

<p><a href="{% url 'xxx' %}">1111111111111</a></p>s

后端方式

语法 reverse('路由的别名')

url(r'^index111/', views.index,name='xxx'),

视图函数层

def index(request):

    if request.method == 'POST':
        url = reverse('xxx')
        return redirect(url)
    return render(request,'index.html')

无名分组反向解析

后端

路由

url(r'^index/([0-9]{4})/', views.index,name='xxx'),

视图函数

def index(request,*age):
   
    rl = reverse('xxx', args=(2019,))
    print(rl)
    return render(request,'index.html')
前端

路由

url(r'^index/([0-9]{4})/', views.index,name='xxx'),

前端html页面

<p> 
    <a href='{ % url 'xxx' 2019 % }'><a>
<p>

有名分组反向解析

后端使用
        # 后端有名分组和无名分组均可以用这种形式
        print(reverse('list',args=(10,)))
        # 下面这个了解便可
        print(reverse('list',kwargs={'year':10}))
    前端使用
        # 前端有名分组和无名分组均可以用这种形式
        {% url 'list' 10 %}
        # 下面这个了解便可
        {% url 'list' year=10 %}

总结:针对有名分组与无名分组的反向解析统一采用一种格式便可
后端
reverse('list',args=(10,)) # 这里的数字一般都是数据的主键值
前端
{% url 'list' 10 %}
反向解析的本质:就是获取到一个可以访问名字所对应的视图函数

路由分发

路由分发
    django每个app下面均可以有本身的urls.py路由层,templates文件夹,static文件夹
    项目名下urls.py(总路由)再也不作路由与视图函数的匹配关系而是作路由的分发
路由分发的两种方式:
    方式一:
        总路由:
            # 不须要导入任何东西
            url(r'^app01','app01.urls'),
            url(r'^app02','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之间视图函数名重复
    url(r'^app01/',include(app01_urls,namespace='app01')),
    url(r'^app02/',include(app02_urls,namespace='app02'))
app01.urls.py
    from django.conf.urls import url
    from app01 import views
    urlpatterns = [
        url(r'^index/',views.index,name='index')
    ]

app02.urls.py
    from django.conf.urls import url
    from app02 import views
    urlpatterns = [
        url(r'^index/',views.index,name='index')
    ]

app01.views.py
reverse('app01:index')

app02.views.py
reverse('app02:index')

伪静态网页:

伪静态网页
    搜索优化seo
    url(r'^index.html',views.index,name='app01_index')

虚拟环境

虚拟环境
    不一样的项目配置不一样的python解释器

django1.0与django2.0之间的区别
    django2.0里面的path第一个参数不支持正则,你写什么就匹配,100%精准匹配
    
    django2.0里面的re_path对应着django1.0里面的url
    
虽然django2.0里面的path不支持正则表达式,可是它提供五个默认的转换器

    str,匹配除了路径分隔符(/)以外的非空字符串,这是默认的形式
    int,匹配正整数,包含0。
    slug,匹配字母、数字以及横杠、下划线组成的字符串。
    uuid,匹配格式化的uuid,如 075194d3-6885-417e-a8a8-6c931e272f00。
    path,匹配任何非空字符串,包含了路径分隔符(/)(不能用?)

自定义转换器
    1.正则表达式
    2.类
    3.注册

# 自定义转换器
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')
PS:路由匹配到的数据默认都是字符串形式

FBV与CBV

FBV与CBV
FBV:基于函数的视图
CBV:基于类的视图

CBV:
    url(r'^mycls/',views.MyCls.as_view())

    class MyCls(View):
        def get(self,request):
            return render(request,'index.html')
        def post(self,request):
            return HttpResponse('post')

不管是FBV仍是CBV路由层都是路由对应视图函数内存地址
urlpatterns = [
    # url(r'^mycls/',views.view)
    url(r'^mycls/',views.MyCls.as_view())
]

class MyCls(View):
    def get(self,request):
        return render(request,'index.html')
    def post(self,request):
        return HttpResponse('post')
简单的文件上传
前端须要注意的点:
    1.method须要指定成post
    2.enctype须要改成formdata格式

后端暂时须要注意的是
    1.配置文件中注释掉csrfmiddleware中间件
    2.经过request.FILES获取用户上传的post文件数据
    
file_obj = request.FILES.get('my_file')
    print(file_obj.name)
    with open(file_obj.name,'wb') as f:
        for line in file_obj.chunks():
            f.write(line)
相关文章
相关标签/搜索