• python :Django url /views /Template 文件介绍


    1,Django URL 路由系统

      URL配置(URLconf)就像Django 所支撑网站的目录。它的本质是URL模式以及要为该URL模式调用的视图函数之间的映射表;你就是以这种方式告诉Django,对于这个URL调用这段代码,对于那个URL调用那段代码。

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

    参数说明:

    • 一个正则表达式字符串
    • 一个可调用对象,通常为一个视图函数或一个指定视图函数路径的字符串
    • 可选的要传递给视图函数的默认参数(字典形式)
    • 一个可选的name参数
    from django.conf.urls import url
    from django.contrib import admin
    
    from app01 import views
    #导入了 应用下的,视图函数 views
    
    
    urlpatterns = [
        path('admin/', admin.site.urls),
        path('index/', views.index),
        #index/网页上的路径,views.index指的是views下的index函数
        path('books_login/',views.books_login ),
    
        path('register/',views.register,name = "reg"),#别名
        # 前端  {% load static %}   路径可以写action="{% url 'reg' %}
    #在前端在想把 某些字段传送给 后台的某个函数,需要些一个路径时,如本来要写。127.0.0.1:8000/register   .现在只要写"{% url 'reg' %} 即可。而且必须在前端的HTML 上写上{% load static %}   加载本地变量
    
    
        path('inster/(d[4])/(d[2])',views.fun)
        这里可以写正则,后面的的正则分组,可以传入参数,在views的功能函数中可以传参

    FBV和CBV

    FBV:UR对应函数式编程

    CBV:URL对应类编程

    如果视图里面写的类时,URL怎么写呢 ?(views放置在book_login文件夹下的,Cbv.py文件)

    path('CBV/', book_login.Cbv.as_view()),
    #目录,类名,as_view()固定写法

    视图CLASS

    from django.views import View#需要继承这个才可以使用类
    
    class Cbv(View):
        def get(self,request):#通过get方式发送过来的数据通过此函数处理
            pass
    
    
        def post(self,request):#通过post方式发送过来的数据通过此函数处理
            pass
    CBV

     http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace']  #类里面执行这些请求函数,都会先去找dispatch

    备注:

    1、关于别名,实际场景中,使用别名可以更好的维护代码,例如,实际路径你可以变,但是别名,还是最初的别名。就不用了代码了

    2、关于正则这里,可以分组,也可不分组,分组的话,可以给视图传参  比如

     def fun(requst,year,month):
        return HttpResponse(y,m)
    
    #如果URL里面这样写的话,那就是给这个函数起了个别名。到时候需要在传递参数的时候,也要使用此别名。
     path('inster/(?P<year>d[4])/(?P<month>d[2])',views.fun)
    
    def fun(requst,year,month):
        return HttpResponse(y,m)#命名

      路由分发

      创建一个项目后,有很多应用,那我们的项目中的url里面的路径太多了,就需要分层来写url了,在项目下应用中新建一个url.py文件。在项目的url文件中,输入

    urlpatterns_test = [
         path('Tbook/', include('Tbook.urls')),
    ]
    #所有关于Tbook的应用都有Tbook下的urls来处理

    那应用中的url文件,到时候从项目中拷贝一个,然后再修改一下即可。

    2,Django views 视图函数

    http请求中产生两个核心对象:

    例如:如果用户给服务器,上传数据,到哪里了。然后。你接收到数据后,应该给用户返回什么?这就出现了,

            http请求:HttpRequest对象

            http响应:HttpResponse对象

    所在位置:django.http

    之前我们用到的参数request就是HttpRequest    检测方法:isinstance(request,HttpRequest)。

    from django.shortcuts import render
    from django.http import HttpResponse, HttpRequest
    def register(requst):
        if requst.method=="POST":
        #判断用户是否使用的是POST方式来传回数据
            print(requst.POST.get("user"))
        #通过此方法来取数据,数据类型是字典。    
            print(requst.POST.get("user"))
            return HttpResponse("ok")
        return render(requst,"name.html")
    
    #参数requst下封装了 请求体。
    # GET:         包含所有HTTP GET参数的类字典对象
    #
    # POST:       包含所有HTTP POST参数的类字典对象
    #
    #              服务器收到空的POST请求的情况也是可能发生的,也就是说,表单form通过
    #              HTTP POST方法提交请求,但是表单中可能没有数据,因此不能使用
    #              if req.POST来判断是否使用了HTTP POST 方法;应该使用  if req.method=="POST"
    View Code

     HttpResponse对象:

      对于HttpRequest对象来说,是由django自动创建的,但是,HttpResponse对象就必须我们自己创建。每个view请求处理方法必须返回一个HttpResponse对象。

      HttpResponse类在django.http.HttpResponse

      在HttpResponse对象上扩展的常用方法:

    页面渲染:         render(requst,"index")
     render_to_response()
    备注:render_to_response() 和render的区别就是不用在参数中写requst
    页面跳转:         redirect("路径")
    locals():    可以直接将函数中所有的变量传给模板
    def books_login(requst):
        t =time.ctime()
        return render(requst,'name.html',{'time':t})
    
    把time渲染到前端,前端可以使用time这个变量。
    
    前端使用时 {{time }} 来使用 ,再使用路径别名时,是用的{% %}
    return render(requst,'name.html',locals())  这样就可以当前视图里面的函数全部传过去。
    redirect("路径")
    def register(requst):
        print(requst.path)#
        print(requst.get_full_path())
        if requst.method == "POST":
            user =requst.POST.get("user")
            if user == "xfd":
                return redirect('/login')
            return HttpResponse("ok")
    
        return render(requst,"name.html")
    #备注:写入路径,一般不会写个什么www......。
    例如#当用户注册完之后,直接跳转至登录界面。

     例

    -----------------------------------url.py
    
     url(r"login",   views.login),
     url(r"xfd_back",   views.xfdn_back),
    
    -----------------------------------views.py
    def login(req):
        if req.method=="POST":
            if 1:#cooks
                # return redirect("/yuan_back/")
                name="xfd"
    
                return render(req,"my backend.html",locals())
    
        return render(req,"login.html",locals())
    
    
    def yuan_back(req):
    
        name="xfd"
    
        return render(req,"my backend.html",locals())
    
    -----------------------------------login.html
    
    <form action="/login/" method="post">
        <p>姓名<input type="text" name="username"></p>
        <p>性别<input type="text" name="sex"></p>
        <p>邮箱<input type="text" name="email"></p>
        <p><input type="submit" value="submit"></p>
    </form>
    -----------------------------------my backend.html
    <h1>用户{{ name }}你好</h1>
    
    #总结: render和redirect的区别:
    #   1 if render的页面需要模板语言渲染,需要的将数据库的数据加载到html,那么所有的这一部分
    #     除了写在yuan_back的视图函数中,必须还要写在login中,代码重复,没有解耦.
    
    #   2 the most important: url没有跳转到/yuan_back/,而是还在/login/,所以当刷新后
    #     又得重新登录.
    登录

    提示,dispatch 。继承VIEWS父类方法

    from django.views import View#需要继承这个才可以使用类
    #当URL来找功能函数时(GET,POST),他会先找dispath...通过dispaht来
    #寻找是否使用POST还是GET。
    #提示有时候需要GET和POST都需要执行的东西的话,可以放在dispatch中
    class Cbv(View):
        def dispatch(self, request, *args, **kwargs):
            result = super(Cbv,self).dispatch(request, *args, **kwargs)
            return result
    
        def get(self,request):#通过get方式发送过来的数据通过此函数处理
            pass
    
    
        def post(self,request):#通过post方式发送过来的数据通过此函数处理
            pass
    类方法执行之前先执行dispatch

    3,Templates 模板

    (1)组成:HTML代码+逻辑控制代码[python代码]

    (2)逻辑控制代码的组成

    a:变量(使用双大括号引用变量)

     {{var_name}}

    例子

    >>> python manange.py shell  (进入该django项目的环境)
    >>> from django.template import Context, Template
    >>> t = Template('My name is {{ name }}.')
    >>> c = Context({'name': 'Stephane'})
    >>> t.render(c)
    'My name is Stephane.'
    
    
    # 同一模板,多个上下文,一旦有了模板对象,你就可以通过它渲染多个context,无论何时我们都可以
    # 像这样使用同一模板源渲染多个context,只进行 一次模板创建然后多次调用render()方法渲染会
    # 更为高效:
    # Low
    for name in ('John', 'Julie', 'Pat'):
        t = Template('Hello, {{ name }}')
        print t.render(Context({'name': name}))
    
    # Good
    t = Template('Hello, {{ name }}')
    for name in ('John', 'Julie', 'Pat'):
        print t.render(Context({'name': name}))
    Template/Context

    在上面的例子中,我们通过 context 传递的简单参数值主要是字符串,然而,模板系统能够非常简洁地处理更加复杂的数据结构,例如list、dictionary和自定义的对象。

    在 Django 模板中遍历复杂数据结构的关键是句点字符 (.)。

    views
    ---------------------------------------------------
    
    def index(request):
        l = ["sjc", "xfd", "sjy"]
        d = {"name":"sunjinchao","age":18}
        return render(request, 'name.html', locals())
    
    ————————————————————————
    Templates/index
    
    {{l}}#  在前端语言中,显示['sjc','xfd','sjy']}
    {{l.1}}#  在前端语言中,显示sjc
    {{l.2}}#  在前端语言中,显示xfd  类似索引
    {{ d.name}}# sunjinchao
    #类对象和 字典的使用方法一致
    万能句点符.与{{}}

    b :变量的过滤器(filter)的使用

     语法格式:{{obj|filter:param}}
    
    # 1  add          :   给变量加上相应的值
       #
       # 2  addslashes   :    给变量中的引号前加上斜线
       #
       # 3  capfirst     :    首字母大写
       #
       # 4  cut          :   从字符串中移除指定的字符
       #
       # 5  date         :   格式化日期字符串
       #
       # 6  default      :   如果值是False,就替换成设置的默认值,否则就是用本来的值
       #
       # 7  default_if_none:  如果值是None,就替换成设置的默认值,否则就使用本来的值
    
    例如:
    
    {{test}}#代表10
    {{test | add:10}}  前端显示20
    过滤

    (3)标签(tag)的使用(使用大括号和百分比的组合来表示使用tag)

    a:{% if %} 的使用 

    {% if num >= 100 and 8 %}
    
        {% if num > 200 %}
            <p>num大于200</p>
        {% else %}
            <p>num大于100小于200</p>
        {% endif %}
    
    {% elif num < 100%}
        <p>num小于100</p>
    
    {% else %}
        <p>num等于100</p>
    
    {% endif %}
    
    
    
    {% if %} 标签接受and,or或者not来测试多个变量值或者否定一个给定的变量
    {% if %} 标签不允许同一标签里同时出现and和or,否则逻辑容易产生歧义,例如下面的标签是不合法的:
    
    {% if obj1 and obj2 or obj3 %}
    if .....end if

    b:{% for %}的使用

    <ul>
    {% for obj in list %}
        <li>{{ obj.name }}</li>
    {% endfor %}
    </ul>
    
    
    #在标签里添加reversed来反序循环列表:
    
        {% for obj in list reversed %}
        ...
        {% endfor %}
    
    #{% for %}标签可以嵌套:
    
        {% for country in countries %}
            <h1>{{ country.name }}</h1>
            <ul>
             {% for city in country.city_list %}
                <li>{{ city }}</li>
             {% endfor %}
            </ul>
        {% endfor %}
    
    
    #系统不支持中断循环,系统也不支持continue语句,{% for %}标签内置了一个forloop模板变量,
    #这个变量含有一些属性可以提供给你一些关于循环的信息
    
    1,forloop.counter表示循环的次数,它从1开始计数,第一次循环设为1:
    
        {% for item in todo_list %}
            <p>{{ forloop.counter }}: {{ item }}</p>
        {% endfor %}
    2,forloop.counter0 类似于forloop.counter,但它是从0开始计数,第一次循环设为0
    3,forloop.revcounter
    4,forloop.revcounter0
    5,forloop.first当第一次循环时值为True,在特别情况下很有用:
    
        
        {% for object in objects %}   
             {% if forloop.first %}<li class="first">{% else %}<li>{% endif %}   
             {{ object }}   
            </li>  
        {% endfor %}  
        
    # 富有魔力的forloop变量只能在循环中得到,当模板解析器到达{% endfor %}时forloop就消失了
    # 如果你的模板context已经包含一个叫forloop的变量,Django会用{% for %}标签替代它
    # Django会在for标签的块中覆盖你定义的forloop变量的值
    # 在其他非循环的地方,你的forloop变量仍然可用
    
    
    #{% empty %}
    
    {{li }}
          {%  for i in li %}
              <li>{{ forloop.counter0 }}----{{ i }}</li>
          {% empty %}
              <li>this is empty!</li>
          {% endfor %}
    
    #         [11, 22, 33, 44, 55]
    #            0----11
    #            1----22
    #            2----33
    #            3----44
    #            4----55
    for..i ...in

    {%for i in rang%}

    {% empty%}#判断对象是否为空

      <H1> 你浏览的文章为空<h1>

    {%endfor%}

    c:{%csrf_token%}:csrf_token标签

         用于生成csrf_token的标签,用于防治跨站攻击验证。注意如果你在view的index里用的是render_to_response方法,不会生效

         其实,这里是会生成一个input标签,和其他表单标签一起提交给后台的。

    d:{% with %}:用更简单的变量名替代复杂的变量名

    {% with total=fhjsaldfhjsdfhlasdfhljsdal %}
     {{ total }} 
    {% endwith %}

    c:{% verbatim %}: 禁止render(如果确实要2个大括号,而不是一个变量的时候使用。【用render后,双大括号里面的文字是变量】)

    {% verbatim %}
             {{ hello }}
    {% endverbatim %}

    d:{% load %}: 加载标签库

    (4):自定义filter和simple_tag(ptyhon自带的函数也就是【B:过滤器】满足不了实际情况时可自定义撰写)

    ------a、在app中创建templatetags模块(必须的)

    ------b、创建任意 .py 文件,如:my_tags.py

    from django import template
    from django.utils.safestring import mark_safe
    
    register = template.Library()   #register的名字是固定的,不可改变
    
    
    @register.filter
    def filter_multi(v1,v2):
        return  v1 * v2
    自定义filter

    ------c、在使用自定义simple_tag和filter的html文件中导入之前创建的 my_tags.py :{% load my_tags %}

    ------d、使用simple_tag和filter(如何调用)

    -------------------------------.html
    {% load xxx %}   #首行
        
        
        
        
     # num=12
    {{ num|filter_multi:2 }} #24
    
    {{ num|filter_multi:"[22,333,4444]" }}
    
    
    {% simple_tag_multi 2 5 %}  参数不限,但不能放在if for语句中
    {% simple_tag_multi num 5 %}
    filter使用

    ------e、在settings中的INSTALLED_APPS配置当前app,不然django无法找到自定义的simple_tag.

    注意:

    filter可以用在if等语句后,simple_tag不可以用在控制语句内。

    (5)extend模板继承

    在整个网站中,如何减少共用页面区域(比如站点导航)所引起的重复和冗余代码?

    #在 模板的 html[text.html]文件中输入
    #把需要更改的部分的代码用block包裹进去。为他起个名字。
    {%block content%}
    
    <h1>不要需要继承的部分<h1>
    
    {%endblock%}
    
    ______________________________________________
    
    
    #子 html文件中  
    {% extends "text.html" %}#写在最顶端
    
    {%block content%}
    
    <h1>修改后的代码<h1>
    
    {%endblock%}
    
    #这样就把test.html中不包含的代码都继承过来。
    #一般来说,block块越多越好。这样解耦性更强。
    模板继承

    (6)模板引入。

    {% include %} 。该标签允许在(模板中)包含其它的模板的内容。 标签的参数是所要包含的模板名称,可以是一个变量,也可以是用单/双引号硬编码的字符串。 每当在多个模板中出现相同的代码时,就应该考虑是否要使用 {% include %} 来减少重复。

    #当有一个html文件,的模板比较中意,切你需要时。可以引入整个WEB文件。
    
    
    {% load static%}#放在HTML上面
    
    {% include “test.html” %}#再需要的地方加上此代码。
    模板引入

     

  • 相关阅读:
    阅读笔记十四
    惨淡的蓝桥杯国赛经历
    阅读笔记十三
    阅读笔记十二
    阅读笔记十一
    阅读笔记十
    阅读笔记九
    阅读笔记八
    阅读笔记七
    阅读笔记六
  • 原文地址:https://www.cnblogs.com/sunjinchao/p/12055764.html
Copyright © 2020-2023  润新知