路由系统和模板基础

1. url的复习
    网址 全球统一资源定位符
    格式 协议(http,HTTPS,ftp等)+域名(ip地址和端口)+路径+参数
2.django的路由系统
    当一个请求来到时
    1.首先到项目目录下的urls.py (根URLconf模块)中,查找路由规则
    2.根URLconf模块,里面定义了 urlpatterns 变量
    3.urlpatterns 是一个(django.urls.path,django.urls.re_path 对象)列表    其中django.urls.path和django.urls.re_path都是django中的方法
    4.按顺序运行每个url模式,在第一个匹配的模式停止
    5.一旦匹配,django导入并调用给定的视图
    6.如果中间出错,或者没有匹配到,返回404

    -path(route, view, kwargs=None, name=None)
        - route 是一个字符串的url规则
        - view 是个视图,表示给定的路径会调用的视图,写上调用的方法,不要加括号
        - kwargs 不是不定长参数,而是额外参数,传递给view,必须是一个字典
        - name url的命名
        前两个参数是必须的
        
    - 在url中捕获参数
        在url规则中使用`<变量名>`可以捕获url中的值,注意是写在前边的route里,路径后边比如'detail/<变量名>/',url的route里的参数,要和views里的方法里的参数一 一对应,

urlpatterns = [
    path('home/', views.index, name='index'),
    path('detail/<int:pk>/', views.detail, kwargs={'status': True}),
    re_path(r'students/(?P<year>\d{4})/(?P<month>[0-9]|1[0-2])/', views.students),
    path('login/', views.login)
]

            多个参数 1)views.py中的函数里,加上其他参数,在urls中的路由方法里,detail/<变量名1>/<变量名2>/,变量1,2的顺序可以换,但是访问页面的时候在浏览器中传参要按照urls中设置的顺序
                          2)参数之间也可以不用/,可以用连接符-,访问网页的时候在浏览器中输入的url的参数之间也要用连接符,别的符号链接也可以,比如+,~,,(注意这里,也可以),.,[等

def detail(request,pk,status):#pk是主键
    return HttpResponse("离开学还有%s天,你作业做完没,道路千万条,学习第一条,作业没写完,开学两行泪!" % pk)
def students(request,year,month):
    return HttpResponse("%s年%s月报名的学生列表" % (year, month))

        传递给视图 ,匹配了url之后调用视图的时候传递给视图的是关键字参数,url路径中不分组则按照位置参数传
        ** 捕获的值是 字符串   url中域名后边的东西,会被传递到urls的urlpatterns里边对应的路径方法中,
    - 路径转换器 限制传递进来的参数,也是写在urlpatterns里的路径里,它限制了url传进来的参数,必须是路径转换器设置的数据类型(试过了能转换成该类型的数据类型也不可以,必须得是那个数据类型),并且从路径传给视图的参数的类型就是路径中规定的数据类型
        案例:<int:pk>

path('detail/<int:pk>/', views.detail, kwargs={'status': True}),

        常用的转换器:
            - str 匹配除了‘/'路径分隔符之外的所有字符串
            - int 匹配任意整数
            - slug 匹配任意ascii字符 加上连字符和下划线
            - uuid 格式化id,通用唯一识别码(Universally Unique Identifier)的缩写UUID是指在一台机器上生成的数字,
                它保证对在同一时空中的所有机器都是唯一的。通常平台会提供生成的API。按照开放软件基金会(OSF)制定的标准计算,用到了以太网卡地址、纳秒级时间、芯片ID码和随机数。
            - path 匹配任意非空字符
    - 使用正则表达式 re_path(route, view, kwargs=None, name=None),首先要导入re_path()模块,写在上边的from django.urls import path的path后面就可以了
        在views里和上面一样,在浏览器中输入url时,参数也是那样传递,
        在urlpatterns里面,方法不是path(),要用re_path(),第一个参数的引号前加r,r""
        python 中 正则表达式的分组命名  (?<name>pattern) 具体例子是r'(?P<year>\d{4})'或者4个\d,然后/(?P<month>[0-9]|1[0-2])/,连起来就是re_path(r'(students/(?P<year>\d{4})/(?P<month>[0-9]|1[0-2])/',views.students)
    

re_path(r'students/(?P<year>\d{4})/(?P<month>[0-9]|1[0-2])/', views.students),

    - django 搜索 url 搜索的是什么?
        只搜索路径部分,跟参数,以及请求方法(get,post)无关
        
        同一个url 可以匹配 get, post

    - 包含其他URLconfs:一般很少把视图函数写在公共的项目文件夹下,一般写在app里,如何指定app中的路径,需要在app中新建urls.py,然后在项目文件夹的urls.py中
        include: 1)导入:在导入path和re_path后加上include
            2)项目中的urls去定义app中的urls :在项目文件夹的urls.py中的urlpatterns加上path("appname/",include('appname.urls')),
                注意include里的文件名后面的.urls是你在app文件夹中创建的那个,也可以不叫urls,但是最好叫urls,appname.urls要加引号括起来
            3)在app的urls.py中的urlpatterns中,先导入:from django.urls import path,re_path后加上include,以及from . import views
            4)定义path()或re_path(),视图函数的相对路径也是和urls文件平级的
            5)运行后浏览器访问的时候url中的路径 要先写appname然后/app中的视图函数
        原理,访问的时候url先经过根urls.py,匹配到appname,先切掉appname的部分,剩下的传到include里边的appname.urls里,在那里面匹配剩下的,
            前边的路由如果传进来参数,也是可以传递到include里边的,在include里边对应的app.urls中继续匹配路径,匹配到之后传递给app中相应的视图函数,
            这样在根urls中设置了"appname-<参数>/"会传给app中的每个路径,如果在相应app的视图函数中没有参数接收他就会报错
            
        
    - 传递额外参数
        1path,re_path 方法中,传递一个kwargs 的字典参数,传递给视图函数,不能urls中定义了额外参数而在视图函数中没有参数接收他        
        2***** 当kwargs 中的key 与 url捕获中的key 一致的时候,以kwargs为准,比如path('detail/<int:pk>/',views.detail,kwargs={'pk':10}),如果访问网址中输入别的数字,最终传给视图函数的还是10
        3如果在项目文件夹的urls中的include路径中加上kwargs={'somekey':"somevalue"},就会把这个额外参数传递给该app的每个视图函数,相当于给app中的urls中的每个路径加上kwargs={'somekey':"somevalue"}

path('detail/<int:pk>/', views.detail, kwargs={'status': True}),


    - url 命名
        页面重定向 ,跳转页面(响应状态码301) 登录之后, 某个操作之后,django中提供了一个方法redirect,能接收url,返回一个重定向的响应,然后页面就会重定向
        比如在视图函数中,return redirect('http://www.baidu.com')返回重定向的url,也就是在访问该视图时,会自动重定向到指定的url,可以用于登陆页面,
        redirect中也可以“/appname/index/”这里要把相对路径写全,前边也要有/,后面也要有/,但是如果想给路由中的url路径改名,重定向的地方都要改,这样是硬编码,url命名是为了避免硬编码
        在urls.py中urlpatterns中的指定path中加一个name参数 给改名后的url起个名字

 path('home/', views.index, name='index'),

        再在views.py中导入reverse方法,就可以通过这个url的名字反向的解析路由,解析出url,导入后在视图函数中加上url = reverse('index'),返回时return redirect(url),这时候reverse方法会把该url反向解析成urls中给定的path中的全路径

from django.shortcuts import render,redirect,reverse
def login(request):
    url = reverse("app1:index")
    return redirect(url)

    - app_name  同一项目下app名不能重复
        定义在 app文件夹下的urlconf模块中,就是每个app文件夹下urls.py里,都分别加上app_name = app名称,

app_name = 'app1'

  然后在各自views里的reverse('appname:index')

def login(request):
    url = reverse("app1:index")
    return redirect(url)

        如果有多个app都有同名的跳转,则根目录解析时候会调用最后一个include的视图函数,所以必须给每个app起名字
        
3. 模板系统
    html 源码写到模板文件中
    - 模板路径设置
        1)一般模板是放在项目的根目录下的,新建一个templates文件夹,然后配置settings.py
        2)settings里面设置 TEMPLATES,这是一个dict:
            'BACKEND':'django.template.backends.django.DjangoTemplates'是模板的引擎,是后台
                      ‘DIRS’:[]是模板的路径,模板渲染的设置就是要搞它,
        3)先在settings.py中导入os模块,注意settings.py有一行BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 用来取到项目的根目录
        4)在 TEMPLATES中的DIRS这个键的值的列表里边,添加拼接路径os.path.join(BASE_DIR,'templates')告诉django模板从这个文件夹里找,动态获取templates文件夹的路径,

'DIRS': [os.path.join(BASE_DIR,'templates')],

            如果打印os.path.join(BASE_DIR,'templates'),得到的是从home目录开始到templates的绝对路径
            其实放模板的文件夹起其他名字也可以,但是起好名字settings里设置的时候就要用它,不要写错
        5)在templates文件夹中,为想添加模板的app设置各自的文件夹,比如新建一个teacher文件夹,然后在这个文件夹里新建HTML File文档,命名index,编写前端代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>app1_index</title>
</head>
<body>
    <h1>我是app1中的主页面</h1>
    <form action="">
        <p>用户名: <input type="text"></p>
        <p>密码: <input type="password"></p>
        <p><input type="submit" value="登陆"></p>
    </form>
</body>
</html>

        6)在指定的视图中想拿到为它编写的模板 首先from django.template.loader import get_template
        7) 在指定的视图函数中定义tp = get_template('teacher/index.html')也就是说templates不用写,从它里边的路径开始写到想要的html文件就可以,django会默认帮我们把前边路径补上
        8)渲染模板 html = tp.render()     render是调用的方法,得到的是一个模板所定义的html文档的一整个字符串
        9)将html返回出去 return HttpResponse(html)
        10)推荐使用快捷方式:省掉步骤从7到9,直接return render(request,'teacher/index.html')

def index(request):
    return render(request, 'app1/html1.html')

猜你喜欢

转载自www.cnblogs.com/bianyimaomaochong/p/10404386.html
今日推荐