Django之路由层视图层模板层介绍

Posted yangmeichong

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Django之路由层视图层模板层介绍相关的知识,希望对你有一定的参考价值。

一、Django请求生命周期

技术图片

1.路由层urls.py

Django 1.11版本 URLConf官方文档

1.1 urls.py配置基本格式

from django.conf.urls import url

urlpatterns = [
     url(正则表达式, views视图函数,参数,别名),
]

1.11.x版本默认

from django.conf.urls import url

urlpatterns = [
    url(r^admin/, admin.site.urls),
url(r‘^test/$‘, views.test),
] 
# 获取到用户输入的url后,根据正则匹配是否对应
# http://127.0.0.1:8000/test 请求的时候实际是请求了2次,第一次请求是按照浏览器输入的进行请求,但是没有匹配到,第二次请求浏览器会自动在末尾加一个/之后进行匹配,如果还匹配不上直接报错
# 注意事项
1 urlpatterns中的元素按照书写顺序从上往下逐一匹配正则表达式,一旦匹配成功则不再继续。
2 若要从URL中捕获一个值,只需要在它周围放置一对圆括号(分组匹配)。
3 不需要添加一个前导的反斜杠,因为每个URL 都有。例如,应该是^articles 而不是 ^/articles。
4 每个正则表达式前面的r 是可选的但是建议加上。

 

urlpatterns = [
    url(r^admin/, admin.site.urls),
    # url(r‘test/[0-9]4/$‘, views.test),
    # 无名分组:会将分组内的结果 当做位置参数自动传递给后面的视图函数views.py
    url(rtest/([0-9]4)/$, views.test),
    # url(r‘^test/(\\d+)/$‘,views.test),
    # 有名分组:会将分组内的结果 当做关键字参数自动传递给后面的视图函数
    url(r^testadd/(?P<id>[0-9]4)/$,views.testadd),
]
# 无名分组:http://127.0.0.1:8000/test/3333/,视图函数加参数后可以访问,如果不加会提示test() takes 1 positional argument but 2 were given
# 有名分组

 1.2 反向解析

  根据别名动态解析出可以匹配上视图函数之前的url的一个结果(注意:在起别名的时候,一定要保证 所有的别名都不能重复,必须是唯一的)

# urls.py
    url(r^testxxx/,views.test,name=t)
    url(r^test/(\\d+)/$,views.test,name=ttt),

# 前端
    没有正则表达式的反向解析
    % url t %
    无名分组反向解析
    有名分组同上
   有正则表达式的反向解析
   % url ‘ttt‘ 1 % # 数字通常是数据库中字典的pk值
# 后端 from django.shortcuts import render,HttpResponse,redirect,reverse 没有正则表达式的反向解析 reverse(t)
   无名分组反向解析 reverse(
ttt,args=(1,)) #有正则表达式的反向解析函数视图views.py 有名分组同上 # urls.py中使用别名后,testxxx无论怎么变,浏览器中路径也会自动变化,动态解析到前端

有名分组和无名分组能否混合使用?
---有名无名不能混合使用!!!

1.3 页面伪静态

# 伪静态
    让一个动态页面伪装成一个看似数据已经写死了的静态页面
    让搜索引擎加大对你这个页面的搜藏力度
    加大seo查询

例如:10982293.html
https://www.cnblogs.com/Dominic-Ji/articles/10982293.html

 1.4 django版本区别1.x与2.x

1.X
    路由里面用的是url()
2.X
    路由里面的用的是path()
    url第一个参数放的是正则表达式
    而你的path第一个参数写什么就是什么,不支持正则
    如果你还想使用第一个参数是正则的方法
    django2.X版本中有一个叫re_path()
    ps:2.x中re_path就等价于1.x中的url
        
    # 虽然path不支持正则表达式,但是它提供了五种转换器(了解)

2. 视图层

2.1 JsonResponse

# views.py
import json
def index(request):
    d = name:simon,password:123,hobby:读书
    # 前端不支持字典,需要转成json格式
    return HttpResponse(json.dumps(d,ensure_ascii=False))
# 前端页面显示:http://127.0.0.1:8000/index/
"name": "simon", "password": "123", "hobby": "读书"

# 第二种方式:
from django.http import JsonResponse
def index(request):
    d = name:simon,password:123,hobby:读书
    # 前端不支持字典,需要转成json格式
    # return HttpResponse(json.dumps(d))
    return JsonResponse(d)

# JsonResponse直接转换成json格式
# 前端没显示中文,可以通过JsonResponse源代码来看方法
# return JsonResponse(d,json_dumps_params=‘ensure_ascii‘:False)

2.2 FBV与CBV

FBV function based views

CBV class based views

# views.py
from django.views import View
class MyLogin(View):
    def get(self,request):
        return HttpResponse("Get")

    def post(self,request):
        return HttpResponse("Post")

# urls.py中如何添加路径?
# CBV路由配置
url(r^login/,views.MyLogin.as_view()),

# 可以在前端home.html写一个页面测试post提交方式
<form action="/login/" method="post">
    <input type="submit">
</form>

# 可以看到我们访问login直接返回Get
#     访问home.html点击提交就会跳到login页面显示post
# 可以看到get请求来走get,post请求走post

3.模板层

 模板语法--模板传值

# 模板语法 url.py
url(r^demo/,views.demo),
# views.py
def demo(request):
    i = 1
    f = 1.11
    s = hello
    # s = []
    l = [1,2,3,4,5,6,7,8,9]
    t = (1,2,3,4)
    d = name:simon,password:123
    se = 1,2,3,4
    # 通过字典传值方式
    # return render(request,‘demo.html‘,‘xxx‘:[1,2,3,4])
    
    def foo():
        print("foo")
        return "0000000oooooooooo"

    class Demo(object):
        def index(self):
            return index

        @classmethod
        def login(cls):
            return cls

        @staticmethod
        def reg():
            return reg

    obj = Demo()
    return render(request,demo.html,locals())  # locals 会将所在名称空间中的所有名字全部传递给前端页面

# 前端页面
# 第一种传值方式
return render(request,demo.html,xxx:[1,2,3,4])
# 前端使用
 xxx 

# 第二种传值方式
# locals 会将所在名称空间中的所有名字全部传递给前端页面
return render(request,demo.html,locals())
# 前端页面需要将所有定义的:i f s等使用双大括号括起来显示
# 如果是函数传到前端显示
<p> foo  如果是函数名,传递到前端会自动加()调用,将调用后的结果展示到前端页面</p>
#如果是类
#<p> obj.index  只要是方法 都会自动加括号调用</p>#

# 获取列表字典中某一个值
前端 l.0 or d.name

 3.1.过滤器

# 后端3中demo类中直接定义n和i
    import datetime
    ctime = datetime.datetime.now()
    sss = sadfasf sdfasf fasdfsadf sdfa

# 前端:
i|add:19  # 结果:20
n|filesizeformat  # n的值进行转化成文件大小M、G等
 ctime|date:Y-m-d   # 日期获取
 sss|truncatechars:20  # 截断一部分...来省略(20包含3个点)
 sss|truncatewords:2   # 截断,只识别空格
#后端
def demo(request):
    h = "<h1>我是h1标签</h1>"
    s1 = "<script>alter(123)</script>"
    # 后端转义views.py
    from django.utils.safestring import mark_safe
    s2 =  "<h2>我是h2标签</h2>"
    s2 = mark_safe(s2)  # 这样前端就不需要用safe了

# safe告诉前端我这个代码是安全的,可以渲染
# 前端转义
 h|safe 
 s1   # 这个如果加safe,前端就会死循环
 s2 

3.2 标签

# 后端
def demo(request):
    l = [1,2,3,4,5,6,7,8,9]
    s3 = [1,2]
    s4 =[None,1]

# 模板语法的if判断    
# 前端demo.html
% if s3 %
    <p> 有值 s3 </p>  # 返回结果就是这个了
    % else %
    <p>这个东西是空的</p>
% endif %
% if s4.0 %
    <p> 有值 s4 </p>
    % elif s4.1 %
    <p>没值</p>
    % else %
    <p>这个东西是空的</p>
% endif %
# 就算值取不到也不会报错

% for foo in l %
#    # foo为每次列表循环的元素,first为第一个值,last为最后一个值,中间可以#
    % if forloop.first %
            <p>first...</p>
        % elif forloop.last %
            <p>这是last</p>
        % else %
            <p>继续啊~~~</p>
    % endif %
    % empty %
        <p>是空的,不能循环</p>
% endfor %

3.3 模板的继承与导入

# 模板的继承
# 在你想做成模板的页面上 添加block块儿 来标识其他用户可以占用的区域
% extends tmp.html %

    % block content %
                <div class="jumbotron">
                  <h1>Hello, world!</h1>
                  <p>...</p>
                  <p><a class="btn btn-primary btn-lg" href="#" role="button">Learn more</a></p>
                </div>
        % endblock %
# 先在模板中划定区域,之后子板利用block就能够找到模板中可以被使用的区域

# 通常情况下 模板中最少有三个区域
css
content
js
ps:模板中的block块儿越多 页面的可扩展性越高
# 模板的导入
将一块html页面作为模块的方式 导入使用
% include goodpage.html %
将goodpage.html页面内容直接导入到该语句的位置
# 模板的继承与导入
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.bootcss.com/jquery/3.4.0/jquery.min.js"></script>
    <link href="/static/bootstrap-3.3.7/css/bootstrap.min.css" rel="stylesheet">
    <script src="/static/bootstrap-3.3.7/js/bootstrap.min.js"></script>
</head>
<body>
<nav class="navbar navbar-default">
    <div class="container-fluid">
        <!-- Brand and toggle get grouped for better mobile display -->
        <div class="navbar-header">
            <button type="button" class="navbar-toggle collapsed" data-toggle="collapse"
                    data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
                <span class="sr-only">Toggle navigation</span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
            </button>
            <a class="navbar-brand" href="#">Brand</a>
        </div>

        <!-- Collect the nav links, forms, and other content for toggling -->
        <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
            <ul class="nav navbar-nav">
                <li class="active"><a href="#">Link <span class="sr-only">(current)</span></a></li>
                <li><a href="#">Link</a></li>
                <li class="dropdown">
                    <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true"
                       aria-expanded="false">Dropdown <span class="caret"></span></a>
                    <ul class="dropdown-menu">
                        <li><a href="#">Action</a></li>
                        <li><a href="#">Another action</a></li>
                        <li><a href="#">Something else here</a></li>
                        <li role="separator" class="divider"></li>
                        <li><a href="#">Separated link</a></li>
                        <li role="separator" class="divider"></li>
                        <li><a href="#">One more separated link</a></li>
                    </ul>
                </li>
            </ul>
            <form class="navbar-form navbar-left">
                <div class="form-group">
                    <input type="text" class="form-control" placeholder="Search">
                </div>
                <button type="submit" class="btn btn-default">Submit</button>
            </form>
            <ul class="nav navbar-nav navbar-right">
                <li><a href="#">Link</a></li>
                <li class="dropdown">
                    <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true"
                       aria-expanded="false">Dropdown <span class="caret"></span></a>
                    <ul class="dropdown-menu">
                        <li><a href="#">Action</a></li>
                        <li><a href="#">Another action</a></li>
                        <li><a href="#">Something else here</a></li>
                        <li role="separator" class="divider"></li>
                        <li><a href="#">Separated link</a></li>
                    </ul>
                </li>
            </ul>
        </div><!-- /.navbar-collapse -->
    </div><!-- /.container-fluid -->
</nav>
<div class="container-fluid">
    <div class="row">
        <div class="col-md-3">
            <div class="list-group">
                <a href="/loginn/" class="list-group-item active">登录</a>
                <a href="/register/" class="list-group-item">注册</a>
                <a href="#" class="list-group-item">Morbi leo risus</a>
                <a href="#" class="list-group-item">Porta ac consectetur ac</a>
                <a href="#" class="list-group-item">Vestibulum at eros</a>
            </div>
        </div>
        <div class="col-md-9">
            % block content %
            <div class="jumbotron">
                <h1>Hello, world!</h1>
                <p>...</p>
                <p><a class="btn btn-primary btn-lg" href="#" role="button">Learn more</a></p>
            </div>
            % endblock %
        </div>
    </div>

</div>
</body>
</html>

# login.html 模板的导入
% extends ‘tmp.html‘ %

% block content %
<h3>登录</h3>
    <form action="" method="post" class="form-group">
        <p>username:<input type="text" class="form-control"></p>
        <p>password:<input type="text" class="form-control"></p>
        <input type="submit" class="btn btn-danger pull-right">
    </form>
% endblock %

# reg.html模板的导入与继承
% extends ‘tmp.html‘ %

% block content %
#    模板的导入#
    % include ‘good.html‘ %
<h3 class="text-center">注册</h3>
    <form action="" method="post" class="form-group">
        <p>username:<input type="text" class="form-control"></p>
        <p>password:<input type="text" class="form-control"></p>
        <input type="submit" class="btn btn-danger pull-right">
    </form>
% endblock %

 

以上是关于Django之路由层视图层模板层介绍的主要内容,如果未能解决你的问题,请参考以下文章

Django之模板层

DJANGO入门系列之(模板层的简单介绍和视图层的扫尾)

Django之模板层

Django之模板层

Django 路由层,视图层,模板层

[置顶]Django框架