zoukankan      html  css  js  c++  java
  • 【python】-- Django路由系统(网址关系映射)、视图、模板

    Django路由系统(网址关系映射)、视图、模板

    一、路由系统(网址关系映射)

    1、单一路由对应:

    一个url对应一个视图函数(类)

    urls.py:
    url(r'^test', views.test), 
    #url(r'^home', views.Test.as_view()),
    
    views.py:
    def test(request):
        print(request.method)
        return render(request, "home.html")
    """
    class Test(View):
    
        def get(self, request):
            print(request.method)
            return render(request, "home.html")
    
        def post(self, request):
            print(request.method)
            return render(request, "home.html")
    """
    

      

     2、基于正则路由对应:

    多个url对应一个视图

    urls.py
    # 多个url对应一个视图函数,不过在给视图函数传参时,要根据对应形参位置进行传参
    url(r'^detail-(d+)-(d+).html', views.detail),
    # 多个url对应一个视图函数,推荐这种写法,在正则匹配完毕后进行了分组分配,在传参时就可以形参位置变化也没有关系
    url(r'^detail-(?P<nid>d+)-(?P<uid>d+).html', views.detail),
    
    views.py:
    #普通传参
    def detail(request, nid, uid):
        print(nid, uid)
        return HttpResponse("%s - %s" % (nid, uid))
    #args传参
    def detail(request, *args, **kwargs):
        print(args[0], args[1])
        return HttpResponse("%s - %s" % (args[0], args[1]))
    #kwargs传参
    def detail(request, *args, **kwargs):
        print(kwargs["nid"], kwargs["uid"])
        return HttpResponse("%s - %s" % (kwargs["nid"], kwargs["uid"]))
    

    3、name:

    对URL路由关系进行命名,以后可以根据此名称生成自己想要的URL

    urls.py:
    url(r'^url_1/', views.index, name='i1'),
    url(r'^url_2/(d+)/(d+)/', views.index, name='i2'),
    url(r'^url_3/(?P<pid>d+)/(?P<nid>d+)/', views.index, name='i3'),
    		
    views.py:
    from django.urls import reverse
    def func(request, *args, **kwargs):
        url1 = reverse('i1')                              # url_1/
        url2 = reverse('i2', args=(1,2,))                 # url_2/1/2/
        url3 = reverse('i3', kwargs={'pid': 1, "nid": 9}) # url_3/1/9/
    
    
    xxx.html:
        
        {% url "i1" %}               # url_1/
        {% url "i2" 1 2 %}           # url_2/1/2/
        {% url "i3" pid=1 nid=9 %}   # url_3/1/9/
    
    PS:
        # 显示当前的URL
        request.path_info 
    

    4、多级路由:

    多级路由目的避免有多个app时,在project urls.py的路由(网址)因路径名称一致而引起的冲突

    #project/urls.py:
        from django.conf.urls import url, include
        from django.contrib import admin
        urlpatterns = [
            url(r'^app1/', include("app1.urls")),
            url(r'^app2/', include("app2.urls")),
        ]
    
    #app01/urls.py:
        from django.conf.urls import url
        from app1 import views
        urlpatterns = [
            url(r'^test', views.test),
        ]
    
    #app02/urls.py:
        from django.conf.urls import url
        from app2 import views
        urlpatterns = [
            url(r'^test', views.test),
        ]
    

    5、默认值

    在路由关系映射的同时,添加额外参数,views.py中的对应函数可接受参数使用

    #urls.py:
    url(r'^test', views.url_test, {"value": 3}),
    
    #views.py:
    def url_test(request, value):
        print(value)
        return HttpResponse("OK")

    6、命令空间

    在project的urls.py中定义namespace后,在views中的函数会根据指定namespace生成url

    6.1.、project.urls.py

    from django.conf.urls import url, include
    
    
    urlpatterns = [
        url(r'^app1/', include("app1.urls", namespace='name_1')),
        url(r'^app2/', include("app1.urls", namespace='name_2')),
    ]
    

    6.2、app1.urls.py

    from django.conf.urls import url
    from app1 import views
    
    app_name = "app1"  # 如果在project urls.py中定义namespace,那在这里就要定义一下app_name
    
    urlpatterns = [
        url(r'^test$', views.url_test, name='i1'),
    ]
    

    6.3、app1.views.py

    from django.shortcuts import reverse, HttpResponse
    
    
    def url_test(request):
        url_1 = reverse("name_1:i1")
        url_2 = reverse("name_2:i1")
        print(url_1, url_2)
        return HttpResponse("OK")

      

    二、视图

    1、FBV&CBV

    1.1、 FBV (Function Base VIew)在view(视图)中基于函数编写逻辑

    #urls.py:
    url(r'^test', views.test),  # FBV  function base view
    
    
    #views.py:
    def test(request):
        if request.method == "GET":
            return render(request, 'test.html')

    1.2、CBV(Class Base Viev)在view(视图)中基于类编写逻辑

    #urls.py;
    url(r'^home', views.Test.as_view()),  # CBV  class base view   .as_view() Test没有view所以在views.py中Test类中继承Django的View
    
    
    #views.py:
    from django.views import View
    
    
    class Test(View):
    
        # 调用父类中的dispatch方法,并重写
        def dispatch(self, request, *args, **kwargs):  # 通过dispatch的反射可以找到如:get、post方法的起始点
            print("before")
            result = super(Test, self).dispatch(request, *args, **kwargs)
            return result
    
        def get(self, request):
            print(request.method)
            return render(request, "home.html")
    
        def post(self, request):
            print(request.method)
            return render(request, "home.html")
    

     2、HTML from表单提交数据的提取示例:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        <form action="/test" method="POST" enctype="multipart/form-data"><!--enctypes属性没有的话,默认提交的是字符串,无法实现文件上传-->
            <p>
                <input type="text" name="user" placeholder="用户名" />
            </p>
            <p>
                <input type="password" name="pwd" placeholder="密码" />
            </p>
            <p>
                男:<input type="radio"  name="gender" value="1"/>
                女:<input type="radio" name="gender" value="2"/>
                张扬:<input type="radio" name="gender" value="3"/>
            </p>
            <p>
                男:<input type="checkbox"  name="favor" value="11"/>
                女:<input type="checkbox" name="favor" value="22"/>
                张扬:<input type="checkbox" name="favor" value="33"/>
            </p>
            <p>
                <select name="city" multiple>
                    <option value="sh">上海</option>
                    <option value="bj">北京</option>
                    <option value="tj">天津</option>
                </select>
            </p>
            <p>
                <input type="file" name="file"/>
            </p>
    
            <input type="submit" value="提交"/>
        </form>
    </body>
    </html>
    test.html
    def test(request):
        if request.method == "GET":
            return render(request, 'test.html')
        elif request.method == "POST":
            # text
            v = request.POST.get('pwd')   # 获取input输入框输入的value
            print(v)
            # radio
            v0 = request.POST.get('gender')   # 获取radio的value
            print(v0)
            # checkbox
            v1 = request.POST.getlist('favor')   # 获取checkbox多选情况下的value
            print(v1)
            # select
            v2 = request.POST.getlist('city')   # 获取select下拉框multiple情况下的value
            print(v2)
            # file
            obj = request.FILES.get('file')    # 获取上传文件并保存
            print(obj, type(obj), obj.name)
            import os
            file_path = os.path.join('upload', obj.name)
            f = open(file_path, mode="wb")
            for i in obj.chunks():  # chunks()利用生成器,每次只加载部分上传的文件,直至加载完毕
                f.write(i)
            f.close()
            return redirect("/test")
        else:
            # PUT,DELETE,HEAD,OPTION...
            return redirect("/test")
    

    3、查看views.py中的request封装的信息

    from django.core.handlers.wsgi import WSGIRequest
    request.environ
    request.environ['HTTP_USER_AGENT']
    

      

     三、模板

    1、模板的特殊语言

     1 视图中函数:
     2 def func(request):
     3     return render(request, "index.html", {'current_user': "QQ"})
     4 
     5 
     6 index.html:
     7 <html>
     8 ..
     9     <body>
    10         <div>{{current_user}}</div>
    11     </body>
    12 </html>
    变量名
     1 视图函数:
     2 def func(request):
     3     return render(request, "index.html", {'current_user': "QQ", 'user_list': ['1', '2']})
     4 
     5 
     6 index.html:
     7 < html >
     8     ..
     9     < body >
    10         < div > {{current_user}} < / div >
    11         < ul >
    12             { %for row in user_list %}   <!--for循环中嵌套if判断>
    13                 { % if row == "2" %}     <!--if判断>
    14                 < li > {{row}} < / li >
    15                 { % endif %}             <!--结束if判断>
    16             { % endfor %}               <!--结束for循环>
    17         < / ul >
    18     < / body >
    19 < / html >
    for循环,if判断
     1 视图函数:
     2 def func(request):
     3                     return render(request, "index.html", {
     4                                 'current_user': "QQ", 
     5                                 'user_list': ['1','2'], 
     6                                 'user_dict': {'k1': 'v1', 'k2': 'v2'}})
     7 
     8 index.html:
     9 < html >
    10     ..
    11     < body >
    12         <div>{{current_user}}</div>
    13         <a> {{ user_list.1 }} </a>
    14         <a> {{ user_dict.k1 }} </a>
    15         <a> {{ user_dict.k2 }} </a>
    16     < / body >
    17 < / html >
    18 
    19 索引
    索引
     1 试图函数:
     2 USER_DICT = {
     3     "k1": "value1",
     4     "k2": "value2",
     5     "k3": "value3",
     6     "k4": "value4"
     7 }
     8 
     9 def for_dict(request):
    10     return render(request, "index.html", {"user_dict": USER_DICT})
    11 
    12 index.html:
    13 <!DOCTYPE html>
    14 <html>
    15 <head lang="en">
    16     <meta charset="UTF-8">
    17     <title></title>
    18 </head>
    19 <body>
    20     <ul>
    21         {%for key in user_dict.keys%}  <!--循环获取key-->
    22         <li>
    23            {{key}}
    24         </li>
    25         {%endfor%}
    26     </ul>
    27     <ul>
    28         {%for value in user_dict.values%} <!--循环获取value-->
    29         <li>
    30            {{value}}
    31         </li>
    32         {%endfor%}
    33     </ul>
    34     <ul>
    35         {%for key,value in user_dict.items%} <!--循环获取key,value-->
    36         <li>
    37            {{key}}--{{ value }}
    38         </li>
    39         {%endfor%}
    40     </ul>
    41 </body>
    42 </html>
    43 
    44 for循环字典
    for循环字典
    1 <!--表示当前循环的执行次数的整数计数器。这个计数器是从1开始的,所以在第一次循环时forloop.counter 将会被设置为1-->
    2 {% for item in todo_list %}
    3 <p>{{ forloop.counter }}: {{ item }}</p>
    4 {% endfor %}
    5 
    6 
    7 ps:<!--forloop.counter0 类似于 forloop.counter ,但是它是从0计数的。第一次执行循环时这个变量会被设置为0-->
    forloop.counter
    1 <!--布尔值类型,在第一次执行循环时该变量为True-->
    2 {% for object in objects %}
    3 {% if forloop.first %}<li class="first">{% else %}<li>{% endif %}
    4 {{ object }}
    5 </li>
    6 {% endfor %}
    forloop.first
     1 <!--布尔值,在最后一次执行循环时被置为True-->
     2 {% for link in links %}
     3     {{ link }}
     4     {% if not forloop.last %} 
     5     | 
     6     {% endif %}
     7 {% endfor %}
     8 
     9 #结果:
    10 Link1 | Link2 | Link3 | Link4
    forloop.last

    2、模板的继承

    父模板:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>{% block title %} {% endblock %}</title> <!--定义标题继承位置-->
        <link rel="stylesheet" href="/static/commons.css" />
        <style>
            .pg-header{
                height: 50px;
                background-color: seashell;
                color: green;
            }
        </style>
        {% block css %} {% endblock %}  #  <!--定义CSS继承位置-->
    </head>
    <body>
    	<div class="pg-header">oms</div>  
    	{%block content%}{%endblock%}       <!--定义内容继承位置-->
    	<script src="/static/jquery.js"></script>
    	{%block js%}{%endblock%}            <!--定义JavaScript继承位置-->
    </body>
    </html>

    子模板:

    {% extends 'master.html' %}                  <!--声明继承的文件-->
    
    {% block title %}用户管理{% endblock %}      <!--在继承文件的头部位置放入值-->
    
    {% block content %}							 <!--在继承文件的内容位置放入值-->
        <h1>用户管理</h1>tou
        <ul>
            {% for i in u %}
                <li>{{ i }}</li>
            {% endfor %}
        </ul>
    
    {% block css %}                              <!--在继承文件的CSS位置放入自己特有的CSS-->
        <style>
            body{
                background-color: red;
            }
        </style>
    {% endblock %}
    
    {% block js %}                               <!--在继承文件的CSS位置放入自己特有的js-->
        <script></script>
    {% endblock %}

    3、模板的引用

    {% include 'tag.html' %}  <!--直接include想要导入的HTML文本-->
    

    4、自定义simple_tag

    Django提供的模板方法(类似于python的内置函数),以供我们在使用模板的时候,更加方便的对数据进行操作。

    {{ k1|lower }}  # 将所有字母都变为小写
    {{ k1|first|upper }}  # 将首字母变为大写
    {{ k1|truncatewords:"30" }}  # 取变量k1的前30个字符
    {{ item.createTime|date:"Y-m-d H:i:s" }}    # 将时间转为对应格式显示

    当然Django提供的方法是有限的,无法满足我们所有的需求,这个时候就需要自定制更加符合我们自己需求的方法(函数),步骤如下:

    • a.在settings中注册APP
    1 INSTALLED_APPS = [
    2     'django.contrib.admin',
    3     'django.contrib.auth',
    4     'django.contrib.contenttypes',
    5     'django.contrib.sessions',
    6     'django.contrib.messages',
    7     'django.contrib.staticfiles',
    8     'app',
    9 ]
    settings.py中注册app
    • b.在app下创建templatetags目录(templatetags目录名称不可变)
    • c.在templatetags目录下定义test.py文件(py文件名任意)
    • d.在test.py文件中定义自定制函数
    1 from django import template
    2 from django.utils.safestring import mark_safe  
    3 
    4 register = template.Library()  #创建创建template对象 register
    5 
    6 @register.simple_tag           #利用register中对象的simple_tagz函数装饰自定义函数
    7 def addition(a1,a2):
    8     return a1 + a2
    自定义函数
    • e.在模板中引用自定义方法(函数)
     1 {% load test %}              <!--导入刚刚定义的py文件名称-->
     2 <!DOCTYPE html>
     3 <html lang="en">
     4 <head>
     5     <meta charset="UTF-8">
     6     <title></title>
     7 </head>
     8 <body>
     9     {% addition  2  5 %}   <!--导入刚刚定义的函数(方法),参数用空格隔开-->
    10 </body>
    11 </html>
    在模板中引用方法

     5、自定义filter

    步骤与自定义simple_tag步骤一致,只是在引用自定义函数中用的装饰器和模板中的引用方式不同:

    • a、b、c、步骤一致
    • d.在test.py文件中定义自定制函数
    1 from django import template
    2 from django.utils.safestring import mark_safe  
    3 
    4 register = template.Library()  #创建创建template对象 register
    5 
    6 
    7 @register.filter               #利用register中对象的filter函数装饰自定义函数
    8 def addition(a1,a2):
    9     return a1 + str(a2)
    自定义函数
    • e.在模板中引用自定义方法(函数)
     1 {% load test %}              <!--导入刚刚定义的py文件名称-->
     2 <!DOCTYPE html>
     3 <html lang="en">
     4 <head>
     5     <meta charset="UTF-8">
     6     <title></title>
     7 </head>
     8 <body>
     9     {{ 2|addition:30 }}  <!--导入刚刚定义的函数(方法){{ 参数1|addition:参数2 }}-->
    10 </body>
    11 </html>
    在模板中引用方法

     PS:自定义simple_tag和自定义filter的区别。

    • 自定义simple_tag装饰的函数可以传入任意数量的参数,但自定filter只能传入两个参数(间接传入多个参数办法:就是将第二个参数通过"args1,args2,args3"的形式传入,然后通过split()解析获取)
    • 自定义simple_tag装饰的函数不能用于模板if条件,但自定filter用于if条件
  • 相关阅读:
    优化-UITableView性能
    优化-预渲染加速iOS设备的图像显示
    UIWebView
    NSJSONSerialization
    UITableView UITableViewCell NSIndexPath
    NSDictionary NSMutableDictionary
    iOS Delegate NSNotificationCenter
    Php解决跨域名共享session方案整理专题
    memached共享session
    二级域名 session共享
  • 原文地址:https://www.cnblogs.com/Keep-Ambition/p/8432374.html
Copyright © 2011-2022 走看看