zoukankan      html  css  js  c++  java
  • Django之路: 模版篇

    一、Django 模版 

     上章是介绍简单的把django.http.HttpResponse的内容显示到网页上,下面就介绍以下如何使用渲染模版的方法来显示内容。本节代码是基于Django 1.8,但 Django 1.4 - Django 1.9操作都是一样的。 

    温馨提示:如果你想学习Django,那么就请您从现在开始按照笔记记录一步一步的用手把代码敲出来,千万不要偷懒哦。。。。。 

     1、创建一个zqxt_tmpl项目,并创建一个一个learn的应用,

    root@w:~# django-admin startproject zqxt_tmpl    #项目
    root@w:~# cd zqxt_tmpl/
    root@w:~/zqxt_tmpl# python manage.py startapp learn  #应用

     2、在把创建的应用加到settings.INSTALLED_APPS中

    root@w:~/zqxt_tmpl# sudo vi zqxt_tmpl/settings.py
    ................
    INSTALLED_APPS = (
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
        'learn',  #添加的应用
    )

     3、打开learn/views.py写一个首页视图

    root@w:~/zqxt_tmpl# sudo vi learn/views.py 

    from django.shortcuts import render
    def home(request):   #创建一个函数调用home.html
            return render(request, 'home.html')

     4、在learn目录下新建一个templates文件夹,在里面创建一个home.html

    默认配置下,Django的模版系统会知道在app下面找到templates文件夹中的模版文件。

    root@w:~# mkdir zqxt_tmpl/learn/templates
    root@w:~# touch zqxt_tmpl/learn/templates/home.html
    root@w:~# tree zqxt_tmpl
    zqxt_tmpl
    ├── learn
    │   ├── admin.py
    │   ├── __init__.py
    │   ├── models.py
    │   ├── templates
    │   │   └── home.html
    │   ├── tests.py
    │   └── views.py
    ├── manage.py
    └── zqxt_tmpl
        ├── __init__.py
        ├── __init__.pyc
        ├── settings.py
        ├── settings.pyc
        ├── urls.py
        └── wsgi.py

    3 directories, 13 files

     5、在home.html中写一些内容。

    root@w:~# sudo vi zqxt_tmpl/learn/templates/home.html 

    <!DOCTYPE html>
    <html>
    <head>
            <title>欢迎光临</title>  #title头部欢迎语
    </head>
    <body>
    欢迎您访问吴老二博客,希望在此学习愉快 #内部内容
    </body>
    </html>

     6、将视图函数对应的网址,更改zqxt_tmpl/zqxt_tmpl/urls.py

    root@w:~# sudo vi zqxt_tmpl/zqxt_tmpl/urls.py 

    from django.conf.urls import patterns, include, url

    from django.contrib import admin
    admin.autodiscover()

    urlpatterns = patterns('',
        # Examples:
         url(r'^$''learn.views.home', name='home'),#把前面的注释去掉
        # url(r'^blog/', include('blog.urls')),

        url(r'^admin/', include(admin.site.urls)),
    )

     Django 1.8.x及以上:

    from django.conf.urls import include, url
    from django.contrib import admin
    from learn import views as learn_views
     
     
    urlpatterns = [
        url(r'^$', learn_views.home, name='home'), #news
        url(r'^admin/', include(admin.site.urls)),
    ]

     7、【可选】创建数据库表

    root@w:~/zqxt_tmpl# python manage.py syncdb
    Creating tables ...
    Creating table django_admin_log
    Creating table auth_permission
    Creating table auth_group_permissions
    Creating table auth_group
    Creating table auth_user_groups
    Creating table auth_user_user_permissions
    Creating table auth_user
    Creating table django_content_type
    Creating table django_session

    You just installed Django's auth system, which means you don't have any superusers defined.
    Would you like to create one now? (yes/no): yes
    Username (leave blank to use 'root'): root #数据名称默认root
    Email address: 
    Password:   #数据库密码
    Password (again): 
    Superuser created successfully.
    Installing custom SQL ...
    Installing indexes ...
    Installed 0 object(s) from 0 fixture(s)

    Django 1.9.x 及上:

    root@w:~/zqxt_tmpl# python manage.py migrate

      创建数据库虽然不会用,但是可以让一些提示消失(提示你要创建数据库之类的)

    8、运行开发服务器 

    root@w:~/zqxt_tmpl# python manage.py runserver 192.168.1.30:8001   #如果本地测试的话就不需要加IP了
    Validating models...

    0 errors found
    December 24, 2015 - 09:41:55
    Django version 1.6.10, using settings 'zqxt_tmpl.settings'
    Starting development server at http://192.168.1.30:8001/
    Quit the server with CONTROL-C.

     网页测试效果:

     模版补充知识:

    一般的网站通用部分,比如导航,底部,访问统计代码等。

    nav.html bottom.html tongji.html
    root@w:~# cd zqxt_tmpl/learn/templates/
    root@w:~/zqxt_tmpl/learn/templates# touch nav.html bottom.html tongji.html

     可以先写一个base.html来包含这些通用文件(include)

    root@w:~/zqxt_tmpl/learn/templates# sudo vi base.html

    <!DOCTYPE html>
    <html>
    <head>
            <title>{% block title %}默认标题{% endblock %} -吴老二博客</title>
    </head>
    <body>
    {% include 'nav.html' %}
    {% block content %}
    <div>这里是默认内容,所有继承都来自这个模版,如果不覆盖就显示这里的默认内容.</div>
    {% endblock %}
    {% include 'bottom.html' %}
    {% include 'tongji.html' %}
    </body>
    </html>

     如果需要,写足够多的block以便继承的模版可以重写该部分,include是包含其它文件的内容,就是把一些网页共用的部分拿出来,重复利用,改动的时候也方便一些,还可以把广告代码放在一个单独的html中,改动也方便,在用到的时候直接继承base.html就好了,继承后的模版也可以在block块中include其它的模版文件。

    这里用首页home.html,继承或者说扩展(extends)原来的base.html,可以简单的这样写,重写部分代码(默认值部分不用修改)

    root@w:~/zqxt_tmpl/learn/templates# sudo vi home.html 

    <!DOCTYPE html>
    <html>
    <head>
            <title>欢迎光临</title>
    </head>
    <body>
    {% extends 'base.html' %}
    {% block title %}欢迎光临吴老二博客首页{% endblock %}
    {% block content %}
    {% include 'ad.html' %}
    这里是吴老二首页,欢迎光临
    {% endblock %}
    </body>
    </html>

     浏览器浏览效果:

     

     注:模版一般放在app下的templates下,Django会自动找到,加入每个app都有一个index.html,当我们在views.py中使用的时候,如何判断是当前app的home.html呢?

    这就需要把每个app中的templates文件夹在建一个app的名称,仅和该app相关的模版放在app/templates/app目录下。

    例如:项目zqxt下有两个app应用分别为tutorial和tryit 

    root@w:~# django-admin startproject zqxt
    root@w:~# tree zqxt
    zqxt
    ├── manage.py
    └── zqxt
        ├── __init__.py
        ├── settings.py
        ├── urls.py
        └── wsgi.py

    1 directory, 5 files
    root@w:~# cd zqxt 
    root@w:~/zqxt# python manage.py startapp tutorial
    root@w:~/zqxt# python manage.py startapp tryit
    root@w:~/zqxt# cd
    root@w:~# 
    root@w:~# tree zqxt
    zqxt
    ├── manage.py
    ├── tryit
    │?? ├── admin.py
    │?? ├── __init__.py
    │?? ├── models.py
    │?? ├── tests.py
    │?? └── views.py
    ├── tutorial
    │?? ├── admin.py
    │?? ├── __init__.py
    │?? ├── models.py
    │?? ├── tests.py
    │?? └── views.py
    └── zqxt
        ├── __init__.py
        ├── __init__.pyc
        ├── settings.py
        ├── settings.pyc
        ├── urls.py
        └── wsgi.py

    3 directories, 17 files
    root@w:~# cd zqxt/t
    tryit/    tutorial/ 
    root@w:~# cd zqxt/tutorial/
    root@w:~/zqxt/tutorial# mkdir -p templates/tutorial
    root@w:~/zqxt/tutorial# touch templates/tutorial/index.html templates/tutorial/search.html
    root@w:~/zqxt/tutorial# cd ..
    root@w:~/zqxt# cd t
    tryit/    tutorial/ 
    root@w:~/zqxt# cd tryit/
    root@w:~/zqxt/tryit# mkdir -p templates/tryit
    root@w:~/zqxt/tryit# touch templates/tryit/index.html templates/tryit/poll.html
    root@w:~/zqxt/tryit# cd
    root@w:~# tree zqxt
    zqxt
    ├── manage.py
    ├── tryit
    │?? ├── admin.py
    │?? ├── __init__.py
    │?? ├── models.py
    │?? ├── templates
    │?? │?? └── tryit
    │?? │??     ├── index.html
    │?? │??     └── poll.html
    │?? ├── tests.py
    │?? └── views.py
    ├── tutorial
    │?? ├── admin.py
    │?? ├── __init__.py
    │?? ├── models.py
    │?? ├── templates
    │?? │?? └── tutorial
    │?? │??     ├── index.html
    │?? │??     └── search.html
    │?? ├── tests.py
    │?? └── views.py
    └── zqxt
        ├── __init__.py
        ├── __init__.pyc
        ├── settings.py
        ├── settings.pyc
        ├── urls.py
        └── wsgi.py

    7 directories, 21 files
    项目zqxt

     这在使用的时候“tutorial/index.html”和“tryit/index.html”这样作为app名称的一部分,就不会混淆

    二、Django 模版进阶

    以下内容主要是针对Django模板中的循环,条件判断,常用的标签,过滤器的使用。

    1、列表,字典,类的实例的使用

    2、循环:迭代显示列表,字典等中的内容

    3、条件判断:判断是否显示该内容,比如判断是手机访问,还是电脑访问,给出不一样的代码。

    4、标签:for,if这样的功能都是标签。

    5、过滤器:管道符号后面的功能,比如{{ var|length }},求变量长度的length就是一个过滤器。

    经常需要将一个或多个变量共享给多个页面或者所有页面使用,比如在网页上显示来访者的IP,这个可以是用Django上下文渲染器来做。

    实例,显示一个基本的字符串在页面上(在项目zqxt_tmpl上

    root@w:~/zqxt_tmpl/learn# sudo vi views.py

    # -*- coding: utf-8 -*-
    from django.shortcuts import render
    def home(request):
            string = u"我在吴老二博客学习Django,用它来建网站"
            return render(request, 'home.html', {'string': string})

     在视图中锄地了一个字符串名称是string到模版home.html,在模版中这样使用:

    root@w:~/zqxt_tmpl/learn/templates# sudo vi home.html 

    {{ string }}

     浏览器访问,在本机上运行:

    root@w:~/zqxt_tmpl# python manage.py runserver 192.168.1.30:8000
    Validating models...

    0 errors found
    December 25, 2015 - 03:25:16
    Django version 1.6.10, using settings 'zqxt_tmpl.settings'
    Starting development server at http://192.168.1.30:8000/
    Quit the server with CONTROL-C.
    [25/Dec/2015 03:25:32] "GET / HTTP/1.1" 200 53

     浏览器:

     

     实例二:for循环和list内容的显示在zqxt_tmpl/learn/views.py

    root@w:~/zqxt_tmpl# sudo vi learn/views.py

    # -*- coding: utf-8 -*-
    from django.shortcuts import render
    def home(request):
            TutorialList = ["HTML""CSS""jQuery""Django"]
            return render(request, 'home.html', {'TutorialList': TutorialList})

     在视图中传递了一个List到模版zqxt_tmpl/learn/templates/home.html,在模版中使用它:

    root@w:~# sudo vi zqxt_tmpl/learn/templates/home.html 

    教程列表:
    {% for i in TutorialList %}
    {{ i }}
    {% endfor %}

     本地运行服务:

    root@w:~/zqxt_tmpl# python manage.py runserver 192.168.1.30:8000
    Validating models...

    0 errors found
    December 25, 2015 - 03:38:06
    Django version 1.6.10, using settings 'zqxt_tmpl.settings'
    Starting development server at http://192.168.1.30:8000/
    Quit the server with CONTROL-C.
    [25/Dec/2015 03:38:10] "GET / HTTP/1.1" 200 42

     for循环要一个结束标记,上面的代码假如对应的是首页的网址(自己修改urls.py),显示在网页上就是:

     总结:一般的变量之类的用{{}} (变量),功能类的,比如循环,条件判断是用{%     %}(标签)

    实例三:显示字典中的内容:

    root@w:~/zqxt_tmpl# sudo vi learn/views.py

    # -*- coding: utf-8 -*-
    from django.shortcuts import render
    def home(request):
            info_dict = {'site': u'吴老二''content': u'自己建网站'}
    #       TutorialList = ["HTML", "CSS", "jQuery", "Django"]
            return render(request, 'home.html', {'info_dict': info_dict})
    #       return render(request, 'home.html', {'TutorialList': TutorialList})

     为了和上个例子做对比我把上例注释掉了,您也可以注释掉也可以直接删除掉。

    root@w:~/zqxt_tmpl# sudo vi learn/templates/home.html 

    【站点】:{{ info_dict.site }} 【内容】:{{ info_dict.content }}
    #{% for i in TutorialList %}
    #
    {{ i }}
    #
    {% endfor %}

     在模版注释了上个实例您也可以删除,这个实例模版中取字典的键是用info_dict.site,而不是Python中的info_dict['site'],效果如下:

     注:以上实例在浏览器浏览之前都要运行以下python manage.py runserver IP:prot

     还可以这样遍历字典:

    root@w:~/zqxt_tmpl# sudo vi learn/templates/home.html 

    {% for key, value in info_dict.items %}
            {{ key }}: {{ value }}
    {% endfor %}

    其实就是遍历这样一个List:[('content': u'自己建网站'), ('site': u'吴老二')]

     

     实例四:在模版进行条件判断和for循环的详细操作:

    root@w:~/zqxt_tmpl# sudo vi learn/views.py

    # -*- coding: utf-8 -*-
    from django.shortcuts import render
    def home(request):
            List = map(str, range(100)) #一个长度为100的list
            return render(request, 'home.html', {'List': List})

     使用逗号将这些元素连接起来:

    root@w:~/zqxt_tmpl# sudo vi learn/templates/home.html 

    {% for item in List %}
            {{ item }},
    {% endfor %}

     效果如下:

     

    最后一个元素的后面也有一个逗号,这样不是我们想要的,如何判断是不是遍历到最后一个元素呢?

    这里可以用forloop.last这个变量,如果是最后一项其为真,否则为假,更改如下:

    root@w:~/zqxt_tmpl# sudo vi learn/templates/home.html 

    {% for item in List %}
            {{ item }}{% if not forloop.last %},{% endif %} 
    {% endfor %}

    for循环补充如下:

    变量描述

    forloop.counter 索引从1

    forloop.counter0 索引从0

    forloop.revcounter 索引从最大长度到1

    forloop.revcounter0 索引从最大长度到0

    forloop.first 当遍历的元素为第一项时为真

    forloop.last 当遍历的元素为最后一项时为真

    forloop.parentloop 用在嵌套的for循环中,获取上一层for循环的forloop 

    当列表中可能为空值时用for empty

    <ul>
    {% for athlete in athlete_list %}
        <li>{{ athlete.name }}</li>
    {% empty %}
        <li>抱歉,列表为空</li>
    {% endfor %}
    </ul>

     实例五,模版上得到视图对应的网址:

    # views.py
    def add(request, a, b):
        c = int(a) + int(b)
        return HttpResponse(str(c))
     
     
    # urls.py
    urlpatterns = patterns('',
        url(r'^add/(d+)/(d+)/$''app.views.add', name='add'),
    )
     
     
    # template html
    {% url 'add' 4 5 %}

      这样网址上就会显示出:/add/4/5/这个网址,假如我们以后修改urls.py中的

    r'^add/(d+)/(d+)/$'

     这一部分,改成另的,比如:

    r'^jiafa/(d+)/(d+)/$'

     这样,我们不需要在次修改模版,当再次访问的时候,网址就会自动变成/jiafa/4/5/

    注意:如果是Django 1.4的话,需要在模版开头上  {% load url from future %} (如果有 extends 的话,加在 extends 下面)

     这可以使用as语句将内容取别名(相当于定义一个变量),多次使用(但视图名称到网址转换只进行了一次)

    {% url 'some-url-name' arg arg2 as the_url %}
     
    <a href="{{ the_url }}">链接到:{{ the_url }}</a>

     实例六,模版中的逻辑操作

     ==,!=,>=,<=,>,<这些比较都可以在模版中使用,比如:

    {% if var >= 90 %}
    成绩优秀,吴老二博客你没少去吧!学得不错
    {% elif var >= 80 %}
    成绩良好
    {% elif var >= 70 %}
    成绩一般
    {% elif var >= 60 %}
    需要努力
    {% else %}
    不及格啊,大哥!多去吴老二博客学习啊!
    {% endif %}

     and,or,not,in,not in也可以在模版中使用

    假如我们判断num是不是在0到100之间:

    {% if num <= 100 and num >= 0 %}
    num在0到100之间
    {% else %}
    数值不在范围之内!
    {% endif %}

     假如我们判断’wulaoer‘

    {% if 'wulaoer' in List %}
    自强学堂在名单中
    {% endif %}

     实例七,模版中获取当前网址,当前用户等:

     如果不是在 views.py 中用的 render 函数,是render to response的话,需要将request加入到上下文渲染器

    Django 1.8 及以后 修改settings.py

    TEMPLATES = [
        {
            'BACKEND''django.template.backends.django.DjangoTemplates',
            'DIRS': [],
            'APP_DIRS': True,
            'OPTIONS': {
                'context_processors': [
                    ...
                    'django.template.context_processors.request',
                    ...
                ],
            },
        },
    ]

     Django 1.7 及以前修改settings.py:

    如果没有TEMPLATE_CONTEXT_PROCESSORS请自行添加下列默认值:

    TEMPLATE_CONTEXT_PROCESSORS = (
        "django.contrib.auth.context_processors.auth",
        "django.core.context_processors.debug",
        "django.core.context_processors.i18n",
        "django.core.context_processors.media",
        "django.core.context_processors.static",
        "django.core.context_processors.tz",
        "django.contrib.messages.context_processors.messages",
    )

     然后再加上 django.core.context_processors.request

    TEMPLATE_CONTEXT_PROCESSORS = (
        ...
        "django.core.context_processors.request",
        ...
    )

     然后在模版中我们就可以用request了。

    获取当前用户:

    {{ request.user }}

     如果登陆就显示内容,不登陆就不显示内容:

    {% if request.user.is_authenticated %}
        {{ request.user.username }},您好!
    {% else %}
        请登陆,这里放登陆链接
    {% endif %}

     获取当前网址:

    {{ request.path }}

     获取当前GET参数:

    {{ request.GET.urlencode }}

     合并到一起用的一个例子:

    <a href="{{ request.path }}?{{ request.GET.urlencode }}&delete=1">当前网址加参数 delete</a>

     比如我们可以判断delete参数是不是1来删除当前的页面内容。

  • 相关阅读:
    C++ string char[] 转化
    c++ 转化
    2014/4/16
    2014/4/11
    垂直电商现倒闭潮
    经典K线组合图解 > 正文
    上下影线
    分​析​主​力​试​盘​手​法
    nginx重新编译不停服
    nexus
  • 原文地址:https://www.cnblogs.com/wulaoer/p/5072794.html
Copyright © 2011-2022 走看看