• Python Django之路由系统


    1.初识路由系统

      路由系统是用户发请求到URL,然后URL根据路由系统重新指向到函数名的一个对应关系

    2.创建project和app

      django-admin startproject mysite
      cd mysite
      python manage.py startapp appd01

    3.在项目的urls.py中定义路由关系,逻辑关系在views.py中。

      views.py

    from django.shortcuts import render
    from django.shortcuts import HttpResponse
    
    # Create your views here.
    def f1(request):
        return HttpResponse('OK')
    
    def login(request):
        return HttpResponse('Login')
    
    def detail(request,nid):
        print (nid)
        return HttpResponse('Detail')
    
    def detail2(request,nid,nnid):
        print (nid,nnid)
        return HttpResponse('Detail2')
    
    def detail3(request,n1,n2):
        print (n1,n2)
        return HttpResponse('Detail3')

      urls.py

    from app01 import views
    
    
    urlpatterns = [
        # url(r'^admin/', admin.site.urls),
        url(r'^index/', views.f1),
        url(r'^login/', views.login),
        url(r'^login2/', views.login),
        url(r'^detail/(d+)/', views.detail),
        url(r'^detail2/(d+)/(d+)/', views.detail2),
        url(r'^detail3/(?P<n1>d+)/(?P<n2>d+)/', views.detail3),
    ]

     4.路由系统之分页

     urls.py中定义页面与函数的对应关系

    from django.conf.urls import url
    from django.contrib import admin
    from django.shortcuts import HttpResponse
    from app01 import views
    
    urlpatterns = [
        # url(r'^admin/', admin.site.urls),
        # url(r'^index/', views.f1),
        url(r'^login/', views.login),
        url(r'^login2/', views.login),
        url(r'^detail/(d+)/', views.detail),
        url(r'^detail2/(d+)/(d+)/', views.detail2),
        url(r'^detail3/(?P<n1>d+)/(?P<n2>d+)/', views.detail3),
        url(r'^index/(d+)/', views.index),
    ]

      定义views.py

    from django.shortcuts import render
    from django.shortcuts import HttpResponse
    
    # Create your views here.
    def f1(request):
        return HttpResponse('OK')
    
    def login(request):
        return HttpResponse('Login')
    
    def detail(request,nid):
        print (nid)
        return HttpResponse('Detail')
    
    def detail2(request,nid,nnid):
        print (nid,nnid)
        return HttpResponse('Detail2')
    
    def detail3(request,n1,n2):
        print (n1,n2)
        return HttpResponse('Detail3')
    
    
    USER_LIST = []
    for item in range(94):
        temp = {'id':item,'username':'alex'+str(item),'email':'email'+str(item)}
        USER_LIST.append(temp)
    
    def index(request,page):
        page = int(page)
        start = (page -1)*10
        end = page*10
        user_list = USER_LIST[start:end]
        return render(request,'index.html',{'user_list':user_list})

      定义index.html页面

    <body>
        <table>
            <tr>
                <td>ID</td>
                <td>用户名</td>
            </tr>
            {% for item in user_list %}
                <tr>
                    <td>{{ item.id }}</td>
                    <td>{{ item.username }}</td>
                </tr>
            {% endfor %}
        </table>
    </body>

    5.路由系统分页之详细信息

      urls.py

        url(r'^index/(d+)/', views.index),
        url(r'^detail/(d+)/',views.detail)

      views.py

    USER_LIST = []
    for item in range(94):
        temp = {'id':item,'username':'alex'+str(item),'email':'email'+str(item)}
        USER_LIST.append(temp)
    
    def index(request,page):
        page = int(page)
        start = (page -1)*10
        end = page*10
        user_list = USER_LIST[start:end]
        return render(request,'index.html',{'user_list':user_list})
    
    def detail(request,nid):
        nid = int(nid)
        user_list_dict = USER_LIST[nid]
        return render(request,'detail.html',{'user_list_dict':user_list_dict})

      index.html

    <body>
        <table>
            <tr>
                <td>ID</td>
                <td>用户名</td>
            </tr>
            {% for item in user_list %}
                <tr>
                    <td>{{ item.id }}</td>
                    <td>{{ item.username }}</td>
                    <td><a href="/detail/{{ item.id }}">详细信息</a></td>
                </tr>
            {% endfor %}
        </table>
    </body>

      detail.html

    <body>
        <ul>
            <li>{{ user_list_dict.id }}</li>
        </ul>
        <ul>
            <li>{{ user_list_dict.username }}</li>
        </ul>
        <ul>
            <li>{{ user_list_dict.email }}</li>
        </ul>
    </body>

     6.路由分发系统

      加入我们按照系统的模块来分,前端的访问界面用web字段开头,后面的管理模块用manager字段开头,那么需要定义两个虚拟主机,一个app01,一个manager01。

      那么在项目s13day18_django中定义urls.py的时候就需要定义两个虚拟主机的映射关系,这时,可以在单独的虚拟主机中也定义对应的urls.py。

      s13day18_django.urls.py

    from django.conf.urls import url, include
    from django.conf.urls import url
    from django.contrib import admin
    from django.shortcuts import HttpResponse
    from app01 import views
    
    
    urlpatterns = [
        url(r'^web/', include('app01.urls')),
        url(r'^manager/',include('manager01.urls'))
    ]

      app01.urls.py

    urlpatterns = [
        url(r'^index/(d+)/', views.index),
        url(r'^detail/(d+)/',views.detail)
    ]

      manager01.urls.py未定义

      app01.views.py

    USER_LIST = []
    for item in range(94):
        temp = {'id':item,'username':'alex'+str(item),'email':'email'+str(item)}
        USER_LIST.append(temp)
    
    def index(request,page):
        page = int(page)
        start = (page -1)*10
        end = page*10
        user_list = USER_LIST[start:end]
        return render(request,'index.html',{'user_list':user_list})
    
    def detail(request,nid):
        nid = int(nid)
        user_list_dict = USER_LIST[nid]
        return render(request,'detail.html',{'user_list_dict':user_list_dict})

      templates下面的index.html

    <body>
        <table>
            <tr>
                <td>ID</td>
                <td>用户名</td>
            </tr>
            {% for item in user_list %}
                <tr>
                    <td>{{ item.id }}</td>
                    <td>{{ item.username }}</td>
                    <td><a href="/web/detail/{{ item.id }}">详细信息</a></td>
                </tr>
            {% endfor %}
        </table>
    </body>

      以及detail.html

    <body>
        <ul>
            <li>{{ user_list_dict.id }}</li>
        </ul>
        <ul>
            <li>{{ user_list_dict.username }}</li>
        </ul>
        <ul>
            <li>{{ user_list_dict.email }}</li>
        </ul>
    </body>

      以后访问app01或者manager01的APP的时候,需要访问页面中输入http://127.0.0.1:8000/web/index/7/或者http://127.0.0.1:8000/manager/...

     7.模板语言

      在模板语言中使用render传递的变量

        {{ k1 }}
        {{ k2.0 }}
    
        {% for item in k2 %}
            <p>{{ item}},{{ forloop.counter }},{{ forloop.counter0 }},{{ forloop.first }},{{ forloop.last }},{{ forloop.revcounter }}</p>
        {% endfor %}
    
        {% if k1 == 'v1' %}
            <h1>V1</h1>
        {% elif k1 == 'v2' %}
            <h1>V2</h1>
        {% else %}
            <h1>OTHER</h1>
        {% endif %}

      在模板语言中如何使用自定义函数

      a.创建指定文件夹,名称不能改templatetags

      b.创建任意.py文件,写函数,返回值register不能变

    from django import template
    from django.utils.safestring import mark_safe
    from django.template.base import Node,TemplateSyntaxError
    register = template.Library()
    
    @register.filter
    def f1(value):
        return value+'10'

      c.在HTML文件的开头导入自定义模块,并且在HTML文件中使用函数

    {% load xx %}

    ......
    <body>
    {{ k1|f1 }}
    </body>

      d.在项目的settings.py中注册app01

    INSTALLED_APPS = [
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
        'app01',
    ]

      这样就可以在模板中使用自定义的函数了。但是在filter模式中,我们只能传递一个参数,如果要传递多个参数,可以自行分解传递的第一个参数,或者使用simple_tag的方式来处理。

      使用simple_tag,只需要在原有的基础上修改装饰器的名字,然后调用方式修改一下。

    @register.simple_tag
    def f2(s1,s2,s3,s4):
        return s1+s2+s3+s4
     {% f2 1 2 3 4 %}  //f2是函数名,1 2 3 4分别是传递过来的4个参数

      filter可以支持模板语言的if条件,simple_tag不支持

      在xx.py中定义

    @register.filter
    def f3(value):
        if value == 'VVV':
            return True
        else:
            return False

      在template.html中定义

        {% if k1|f3 %}
            <h1>True</h1>
        {% else %}
            <h1>False</h1>
        {% endif %}

     8.模板

      假设我们有一个如下的样示:

       每次点用户管理的时候,用户管理被选中,并且右侧栏显示用户管理的内容,点击资产管理的时候,资产管理被选中,并且右侧栏显示资产管理的内容。最简单的做法是分别再两个页面中添加active的属性,并且显示值。

      userinfo.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title></title>
        <style>
            .pg-header{
                height: 48px;
                background-color: blue;
            }
    
            .pg-body{
                min-height: 500px;
            }
            .pg-body .body-menu{
                 20%;
                float: left;
            }
            .pg-body .body-content{
                 80%;
                float: left;
            }
            .pg-footer{
                height: 100px;
                background-color: brown;
            }
            .active{
                background-color: blueviolet;
                color: white;
            }
        </style>
    </head>
    <body>
        <div class="pg-header"></div>
        <div class="pg-body">
            <div class="body-menu">
                <ul>
                    <li><a href="/web/userinfo" class="active">用户管理</a></li>
                    <li><a href="/web/assets">资产管理</a></li>
                </ul>
            </div>
            <div class="body-content">
                <table border="1" solid red>
                    {% for item in user_list %}
                        <tr>
                            <td>{{ item.username }}</td>
                            <td>{{ item.sexy }}</td>
                        </tr>
                    {% endfor %}
                </table>
            </div>
        </div>
        <div class="pg-footer"></div>
    </body>
    </html>

      assets.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title></title>
        <style>
            .pg-header{
                height: 48px;
                background-color: blue;
            }
    
            .pg-body{
                min-height: 500px;
            }
            .pg-body .body-menu{
                 20%;
                float: left;
            }
            .pg-body .body-content{
                 80%;
                float: left;
            }
            .pg-footer{
                height: 100px;
                background-color: brown;
            }
            .active{
                background-color: blueviolet;
                color: white;
            }
        </style>
    </head>
    <body>
        <div class="pg-header"></div>
        <div class="pg-body">
            <div class="body-menu">
                <ul>
                    <li><a href="/web/userinfo">用户管理</a></li>
                    <li><a href="/web/assets" class="active">资产管理</a></li>
                </ul>
            </div>
            <div class="body-content">
                <table border="1" solid red>
                    {% for item in assets_list %}
                        <tr>
                            <td>{{ item.hostname }}</td>
                            <td>{{ item.port }}</td>
                        </tr>
                    {% endfor %}
                </table>
            </div>
        </div>
        <div class="pg-footer"></div>
    </body>
    </html>

      可以看到,在两段代码中有大量的重用。并且一旦修改,所有页面都要修改,有没有像函数一样可以导入的方式呢,把不变化的内容创建一个模板layout.html。

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title></title>
        <style>
            .pg-header{
                height: 48px;
                background-color: blue;
            }
    
            .pg-body{
                min-height: 500px;
            }
            .pg-body .body-menu{
                width: 20%;
                float: left;
            }
            .pg-body .body-content{
                width: 80%;
                float: left;
            }
            .pg-footer{
                height: 100px;
                background-color: brown;
            }
            .active{
                background-color: blueviolet;
                color: white;
            }
        </style>
    </head>
    <body>
        <div class="pg-header"></div>
        <div class="pg-body">
            <div class="body-menu">
                <ul>
                    <li><a href="/web/userinfo">用户管理</a></li>
                    <li><a href="/web/assets">资产管理</a></li>
                </ul>
            </div>
            <div class="body-content">
                {% block body %}{% endblock %}
            </div>
        </div>
        <div class="pg-footer"></div>
    </body>
    </html>

      assets.html

    {% extends "layout.html" %}
    {% block body %}
            <table border="1" solid red>
                {% for item in assets_list %}
                    <tr>
                        <td>{{ item.hostname }}</td>
                        <td>{{ item.port }}</td>
                    </tr>
                {% endfor %}
            </table>
    {% endblock %}

      userinfo.html

    {% extends "layout.html" %}
    {% block body %}
            <table border="1" solid red>
                {% for item in user_list %}
                    <tr>
                        <td>{{ item.username }}</td>
                        <td>{{ item.sexy }}</td>
                    </tr>
                {% endfor %}
            </table>
    {% endblock %}

      使用上面的方法之后,可以正常的显示页面了,但是选中菜单确没有了。有两种方式可以添加选中菜单,一种依旧是定义一个block,然后重写,另外一种就是给layout里面的元素添加ID,然后通过JS来访问。

      layout.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title></title>
        <style>
            .pg-header{
                height: 48px;
                background-color: blue;
            }
    
            .pg-body{
                min-height: 500px;
            }
            .pg-body .body-menu{
                width: 20%;
                float: left;
            }
            .pg-body .body-content{
                width: 80%;
                float: left;
            }
            .pg-footer{
                height: 100px;
                background-color: brown;
            }
            .active{
                background-color: blueviolet;
                color: white;
            }
        </style>
    </head>
    <body>
        <div class="pg-header"></div>
        <div class="pg-body">
            <div class="body-menu">
                <ul>
                    <li><a id="userinfo" href="/web/userinfo">用户管理</a></li>
                    <li><a id="assets" href="/web/assets">资产管理</a></li>
                    {% block js %}{% endblock %}
                </ul>
            </div>
            <div class="body-content">
                {% block body %}{% endblock %}
            </div>
        </div>
        <div class="pg-footer"></div>
    </body>
    </html>

      userinfo.html

    {% extends "layout.html" %}
    {% block body %}
            <table border="1" solid red>
                {% for item in user_list %}
                    <tr>
                        <td>{{ item.username }}</td>
                        <td>{{ item.sexy }}</td>
                    </tr>
                {% endfor %}
            </table>
    {% endblock %}
    
    {% block js %}
            <script>
                document.getElementById("userinfo").className="active";
            </script>
    {% endblock %}

      assets.html

    {% extends "layout.html" %}
    {% block body %}
            <table border="1" solid red>
                {% for item in assets_list %}
                    <tr>
                        <td>{{ item.hostname }}</td>
                        <td>{{ item.port }}</td>
                    </tr>
                {% endfor %}
            </table>
    {% endblock %}
    
    
    {% block js %}
            <script>
                document.getElementById("assets").className="active";
            </script>
    {% endblock %}

      include的使用,假设在userinfo.html里面经常要使用多个对话框的时候,可以单独将多个对话框拿出来放在一个单独的html文件中,例如pizza.html

    <form>
        <input type="text">
        <input type="text">
        <input type="text">
        <input type="text">
    </form>

      然后要使用的时候,在userinfo.html中直接include即可:

    {% extends "layout.html" %}
    {% block body %}
            <table border="1" solid red>
                {% for item in user_list %}
                    <tr>
                        <td>{{ item.username }}</td>
                        <td>{{ item.sexy }}</td>
                    </tr>
                {% endfor %}
            </table>
            {% include "pizza.html" %}
            {% include "pizza.html" %}
            {% include "pizza.html" %}
    {% endblock %}
    
    {% block js %}
            <script>
                document.getElementById("userinfo").className="active";
            </script>
    {% endblock %}

      

  • 相关阅读:
    JDBC学习总结
    RAD,Eclipse切換界面語言(中日英)
    Eclipse生成EXE文件(可视化Login/读取文件)
    2019年10月 历史记录追加
    如何将eclipse的java导出成exe
    EAR、JAR、WAR(IT)
    Linux命令(IT)
    aarch64 cross compile 交叉编译 opencv
    cross compile vlc 播放器
    cross compile 交叉编译 ffmpeg
  • 原文地址:https://www.cnblogs.com/python-study/p/6018126.html
Copyright © 2020-2023  润新知