python_19(Django外鍵)

第1章 Django ORM相關操做
1.1 在一個py文件中使用django項目
1.2 返回QuerySet對象的方法有
1.2.1 特殊的QuerySet
1.3 返回具體對象的
1.4 返回布爾值的方法有:
1.5 返回數字的方法有
1.6 表單查詢-雙下劃線
1.6.1 id__lt
1.6.2 id__in
1.6.3 name__contains
1.6.4 icontains
1.6.5 id__range
1.6.6 其它
第2章 ForeignKey操做(重點)
2.1 例:
2.1.1 設置model.py給多的添加外鍵
2.1.2 配置urls.py
2.1.3 編寫views.py
2.1.4 service_list.html
2.1.5 server_add.html
第3章 下載文件從存儲驅動
第4章 pycharm中的快捷鍵
4.1 部署配置static
第5章 路由系統進階
5.1 基本格式
5.2 參數說明
5.3 url正則說明
5.3.1 注意事項
5.3.2 APPEND_SLASH=True
5.4 分組命名匹配
5.4.1 位置參數
5.4.2 關鍵字參數(命名分組)
5.4.3 視圖分組(分頁寫法)
5.4.4 規範url路由分發
5.4.5 給視圖參數傳遞額外的參數
5.5 url命名和反向解析(重)
5.5.1 靜態傳參
5.5.2 動態傳參
5.6 命名空間
5.6.1 namespace
第6章 djaango--視圖
6.1 視圖函數FBV
6.2 視圖類CBV
6.2.1 View模塊
6.2.2 .as_view()方法
6.3 裝飾器
6.3.1 FBV裝飾器
6.3.2 CBV裝飾器
6.3.3 介紹
6.3.4 method_decorator模塊
6.3.5 擴展
6.3.6 CBV裝飾器的三種方法
6.3.7 方法一:直接加載方法上面
6.3.8 方法二:加在dispatch方法上面
6.3.9 方法三:加在類上
6.4 request相關參數
6.4.1 path_info
6.4.2 method
6.4.3 GET
6.4.4 POST
6.4.5 body
6.5 屬性
6.5.1 HttpRequest.scheme
6.5.2 HttpRequest.body
6.5.3 HttpRequest.path
6.5.4 HttpRequest.method
6.5.5 HttpRequest.encoding
6.5.6 HttpRequest.GET
6.5.7 6.HttpRequest.POST
6.5.8 HttpRequest.COOKIES
6.5.9 HttpRequest.FILES
6.5.10 HttpRequest.META
6.5.11 HttpRequest.user
6.5.12 HttpRequest.session
6.6 上傳文件
6.7 response
6.7.1 介紹
6.7.2 使用方法
6.7.3 JsonResponse
6.7.4 render()
6.7.5 redirect()
6.7.6 設定json
第7章 模板引擎
7.1 經常使用語法
7.2 變量
7.2.1 例
7.3 Filters
7.3.1 default
7.3.2 filesizeformat
7.3.3 add
7.3.4 lower
7.3.5 title
7.3.6 length
7.3.7 slice
7.3.8 first
7.3.9 last
7.3.10 join
7.3.11 truncatechars
7.3.12 date
7.3.13 safe
7.3.14 自定義filter
7.3.15 for
7.3.16 with
7.3.17 註釋
7.3.18 注意事項
7.4 模板繼承
7.4.1 塊(block)
7.4.2 組件
7.4.3 自定義simpletag
7.4.4 templatetags/my_inclusion.py
7.4.5 templates/result.html
7.4.6 templates/index.html
7.5 bootstrip沒有數據優化 css

第1章 Django ORM相關操做

操做html

查詢結果前端

all():python

查詢全部結果正則表達式

filter(**kwargs):數據庫

它包含了與所給篩選條件相匹配的對象django

get(**kwargs):json

返回與所給篩選條件相匹配的對象,返回結果有且只有一個,若是符合篩選條件的對象超過一個或者沒有都會拋出錯誤。bootstrap

exclude(**kwargs):瀏覽器

它包含了與所給篩選條件不匹配的對象

values(*field):

返回一個ValueQuerySet——一個特殊的QuerySet,運行後獲得的並非一系列model的實例化對象,而是一個可迭代的字典序列

values_list(*field):

它與values()很是類似,它返回的是一個元組序列,values返回的是一個字典序列

order_by(*field):

對查詢結果排序

reverse():

對查詢結果反向排序,請注意reverse()一般只能在具備已定義順序的QuerySet上調用(在model類的Meta中指定ordering或調用order_by()方法)。

distinct():

從返回結果中剔除重複紀錄(若是你查詢跨越多個表,可能在計算QuerySet時獲得重複的結果。此時可使用distinct(),注意只有在PostgreSQL中支持按字段去重。)

count():

返回數據庫中匹配查詢(QuerySet)的對象數量。

first():

返回第一條記錄

last():

返回最後一條記錄

exists():

若是QuerySet包含數據,就返回True,不然返回False

 

1.1 在一個py文件中使用django項目

import os

if __name__=='__main__':

    os.environ.setdefaul("DJANGO_SETTINGS_MODULE","mysite.setting")

    import django

    django.setup()

   

    from app01 import models

    ret = models.Person.objects.filer(age=18)

 

 

1.2 返回QuerySet對象的方法有

l  all()

l  filter()

l  exclude()

l  order_by()

l  reverse()

l  distinct()

1.2.1 特殊的QuerySet

l  values()       返回一個可迭代的字典序列

l  values_list() 返回一個可迭代的元祖序列

1.3 返回具體對象的

l  get()

l  first()

l  last()

1.4 返回布爾值的方法有:

l  exists()

1.5 返回數字的方法有

l  count()

1.6 表單查詢-雙下劃線

1.6.1 id__lt

獲取id大於1 且 小於10的值

models.Tb1.objects.filter(id__lt=10, id__gt=1)

1.6.2 id__in

獲取id等於十一、2二、33的數據

models.Tb1.objects.filter(id__in=[11, 22, 33])  

not in

models.Tb1.objects.exclude(id__in=[11, 22, 33])

1.6.3 name__contains

獲取name字段包含"ven"的

models.Tb1.objects.filter(name__contains="ven")

1.6.4 icontains

大小寫不敏感

models.Tb1.objects.filter(name__icontains="ven")

1.6.5 id__range

id範圍是1到3的,等價於SQL的bettwen and

 models.Tb1.objects.filter(id__range=[1, 3])    

1.6.6 其它

相似的還有:

startswith,istartswith, endswith, iendswith 

date字段還能夠:

models.Class.objects.filter(first_day__year=2017)

 

 

 

第2章 ForeignKey操做(重點)

 

class Publisher(models.Model):

    name = models.CharField(max_length=12)

 

class Book(models.Model):

    title = models.CharField(max_length=32)

    publisher_id = models.ForeignKey(to="Publisher",on_delete=CASCADE)

 

 

注意:on_delete=CASCADE 在Django2.0中要添加,表示級聯刪除之意

解釋:在出版社Publosher刪除後BOOk也隨之級聯的操做,1.1默認是級聯刪除

 

django rest framwork

 

2.1 例:

設置primary外鍵

2.1.1 設置model.py給多的添加外鍵

方法一:

class Publisher(models.Model):

    id = models.AutoField(primary_key=True)

    name =models.CharField(max_length=32)

   

class Book(models.Model):

    title = models.CharField(max_length=32)

    publisher = models.ForeignKey(Publisher)

 

方法二:字符串表示調用的類(不用考慮順序)

class Publisher(models.Model):

    id = models.AutoField(primary_key=True)

    name =models.CharField(max_length=32)

   

class Book(models.Model):

    title = models.CharField(max_length=32)

    publisher = models.ForeignKey('Publisher')#django自動加_id

 

2.1.2 配置urls.py

mtmy/urls.py

from django.conf.urls import url,include

from django.contrib import admin

 

urlpatterns = [

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

    url(r'app01',include('app01.urls'))

]

app01/urls.py

from django.conf.urls import url

from app01 import views

 

urlpatterns = [

 

    url(r'index/$', views.index,),

    # service url

    url(r'service_list/$', views.service_list, name='service_list'),

    url(r'service_list/service_add/$', views.service_add,name='service_add'),

    url(r'service_list/service_del/(?P<pk>\d+)/$', views.service_del,name='service_del'),

    #server url

    url(r'server_list/$',views.server_list,name='server_list'),

    url(r'server_list/server_add/$', views.AddServer.as_view(),name='server_add'),

    url(r'service_list/server_del/(?P<pk>\d+)/$', views.server_del,name='server_del'),

 

    #manage url

    url(r'manage_list/$',views.manage_list,name='manage_list'),

    url(r'manage_list/manage_add/$', views.manage_add,name='manage_add'),

    url(r'manage_list/manage_del/(?P<pk>\d+)/$', views.manage_del,name='manage_del'),

]

 

2.1.3 編寫views.py

 from django.shortcuts import render,redirect,reverse,HttpResponse

from app01 import models

from django.views import View

 

# Create your views here.

 

 

def index(request):

    return render(request, 'index.html')

 

def service_list(request):

    services = models.ServiceList.objects.all()

    #render 返回一個渲染的模板能夠傳入參數

    return render(request,'service_list.html',{'services': services})

 

def service_add(request):

  err_msg = ''

  if request.method == 'POST':

      service_name = request.POST.get('service_name')

      if service_name:

          service_list = models.ServiceList.objects.filter(service_name=service_name)

          if service_list:

              err_msg = '服務名稱已經存在'

          else:

              service_obj = models.ServiceList.objects.create(service_name=service_name)

              print(service_obj)

              #redirect 接收一個url,表示跳轉到指定的url

              return redirect(reverse('service_list'))

  else:

      err_msg = '用戶名不能爲空'

  return render(request,'service_add.html',{'error_msg':err_msg})

 

def service_del(request,pk):

    serv_list = models.ServiceList.objects.filter(id=pk)

    print(serv_list)

    if serv_list:

        serv_list[0].delete()

        return redirect(reverse('service_list'))

    else:

        return HttpResponse('刪除數據不存在')

 

def server_list(request):

    server = models.HostsList.objects.all()

    #render 返回一個渲染的模板能夠傳入參數

    return render(request,'server_list.html',{ 'server':server })

 

def server_del(request,pk):

    # service_id = request.GET.get(pk)

    # print(pk)

    serv_list = models.HostsList.objects.filter(id=pk)

    print(serv_list)

    if serv_list:

        serv_list[0].delete()

        return redirect(reverse('server_list'))

    else:

        return HttpResponse('刪除數據不存在')

 

class AddServer(View):

 

    def get(self,request):

        services = models.ServiceList.objects.all()

        manages = models.ManageList.objects.all()

        return render(request,'server_add.html',{ 'service':services,'manage':manages})

    def post(self,request):

        new_name = self.request.POST.get('server_ip')

        password = self.request.POST.get('password')

        service_id = self.request.POST.get('service')

        manage_id = self.request.POST.get('manage')

        models.HostsList.objects.create(ipaddr=new_name,password=password,service=models.ServiceList.objects.get(id=service_id),manage=models.ManageList.objects.get(id=manage_id))

        return redirect(reverse(server_list))

 

def manage_list(request):

    #獲取數據庫全部數據

    manage_list = models.ManageList.objects.all()

    #render 返回一個渲染的模板能夠傳入參數server表示html中的for 中的server

    return render(request,'manage_list.html',{ 'server':manage_list })

 

def manage_add(request):

  err_msg = ''

  if request.method == 'POST':

      manage_id = request.POST.get('id')

      manage_name = request.POST.get('name')

      manage_pwd = request.POST.get('password')

 

      if manage_id:

          manage_list = models.ManageList.objects.filter(id=manage_id)

          if manage_list:

              err_msg = '服務器已經存在'

          else:

              manage_obj = models.ManageList.objects.create(id=manage_id,password=manage_pwd,name=manage_name)

              # print(service_obj)

              #redirect 接收一個url,表示跳轉到指定的url

              return redirect(reverse('manage_list'))

  else:

      err_msg = '用戶名不能爲空'

  return render(request,'manage_add.html',{'error_msg':err_msg})

 

def manage_del(request,pk):

    # service_id = request.GET.get(pk)

    # print(pk)

    serv_list = models.ManageList.objects.filter(id=pk)

    print(serv_list)

    if serv_list:

        serv_list[0].delete()

        return redirect(reverse('manage_list'))

    else:

        return HttpResponse('刪除數據不存在')

 

2.1.4 service_list.html

{% extends 'base.html' %}

 

{% block content %}

 

    <h2 class="sub-header">服務管理列表</h2>

    <a class="btn btn-success" href="{% url 'service_add' %}">添加</a>

    <div class="table-responsive">

        <table class="table table-bordered table-hover">

            <thead>

            <tr>

                <th>序號</th>

                <th>ID</th>

                <th>服務名稱</th>

                <th>操做</th>

            </tr>

            </thead>

            <tbody>

            {% for service in services %}

                <tr>

                    <td>{{ forloop.counter }}</td>

                    <td>{{ service.id }}</td>

                    <td>{{ service.service_name }}</td>

                    <td>

                        <a class="btn btn-success btn-sm"

                           href="">編輯</a>

                        <a class="btn btn-danger btn-sm" href="{% url 'service_del' pk=service.id %}">刪除</a>

                    </td>

                </tr>

            {% empty %}

                <tr>

                    <td colspan="4" style="text-align: center">沒有數據</td>

                </tr>

            {% endfor %}

 

 

            </tbody>

        </table>

    </div>

{% endblock %}

 

2.1.5 server_add.html

<!DOCTYPE html>

<html lang="en">

<head>

    <meta charset="UTF-8">

    <title>Title</title>

    <link rel="stylesheet" href="/static/bootstrap-3.3.7/css/bootstrap.css">

</head>

<body>

 

{% include 'nav.html' %}

<div class="container" style="margin-top: 70px">

    <div class="row">

        <div class="col-sm-6 col-sm-offset-3">

            <form class="form-horizontal" action="" method="post" novalidate>

                {% csrf_token %}

                <div class="form-group">

                    <label for="inputEmail3" class="col-sm-2 control-label">IPAddr</label>

                    <div class="col-sm-10">

                        <input type="text" name="server_ip" class="form-control" id="inputEmail3" placeholder="請添加服務IP">

                    </div>

                </div>

                <div class="form-group">

                    <label for="inputEmail3" class="col-sm-2 control-label">Password</label>

                    <div class="col-sm-10">

                        <input type="text" name="password" class="form-control" id="inputEmail3" placeholder="請添加服務器密碼">

                    </div>

                </div>

                <div class="form-group">

                    <label for="inputEmail3" class="col-sm-2 control-label">Service_ID</label>

                    <div class="col-sm-10 ">

 

                        <select name="service" class="form-control" >

                            {% for service in service %}

                                <option value="{{ service.id }}">{{ service.service_name }}</option>

                            {% endfor %}

                        </select>

                    </div>

                </div>

                <div class="form-group">

                    <label for="inputEmail3" class="col-sm-2 control-label">Manage_ID</label>

                    <div class="col-sm-10 ">

 

                        <select name="manage" class="form-control" >

                            {% for manage in manage %}

                                <option value="{{ manage.id }}">{{ manage.name }}</option>

                            {% endfor %}

                        </select>

                    </div>

                </div>

                <div class="form-group">

                    <div class="col-sm-offset-2 col-sm-10">

                        <button type="submit" class="btn btn-default">提交</button>

                    </div>

                </div>

            </form>

        </div>

 

    </div>

</div>

 

 

</body>

</html>

第3章 下載文件從存儲驅動

 

 

第4章 pycharm中的快捷鍵

l  Ctrl +d 複製

l  CTrl + shilft + - 合起全部

l  for +Tab html for 循環

l  div. +table

 

4.1 部署配置static

https://docs.djangoproject.com/en/1.11/howto/static-files/deployment/

第5章 路由系統進階

5.1 基本格式

Django1.15寫法:

from django.conf.urls import url

 

urlpatterns = [

     url(正則表達式, views視圖函數,參數,別名),

]

 

Django2.0寫法

from django.urls import path

 

urlpatterns = [

    path('articles/2003/', views.special_case_2003),

    path('articles/<int:year>/', views.year_archive),

    path('articles/<int:year>/<int:month>/', views.month_archive),

    path('articles/<int:year>/<int:month>/<slug:slug>/', views.article_detail),

]

 

5.2 參數說明

l  正則表達式:一個正則表達式字符串

l  views視圖函數:一個可調用對象,一般爲一個視圖函數或一個指定視圖函數路徑的字符串

l  參數:可選的要傳遞給視圖函數的默認參數(字典形式)

l  別名:一個可選的name參數

5.3 url正則說明

from django.conf.urls import url

 

from . import views

 

urlpatterns = [

    url(r'^articles/2003/$', views.special_case_2003),

    url(r'^articles/([0-9]{4})/$', views.year_archive),

    url(r'^articles/([0-9]{4})/([0-9]{2})/$', views.month_archive),

    url(r'^articles/([0-9]{4})/([0-9]{2})/([0-9]+)/$', views.article_detail),

]

5.3.1 注意事項

l  urlpatterns中的元素按照書寫順序從上往下逐一匹配正則表達式,一旦匹配成功則再也不繼續。

l  若要從URL中捕獲一個值,只須要在它周圍放置一對圓括號(分組匹配)。

l  不須要添加一個前導的反斜槓,由於每一個URL 都有。例如,應該是^articles 而不是 ^/articles。

l  每一個正則表達式前面的'r' 是可選的可是建議加上

5.3.2 APPEND_SLASH=True

解釋:

Django settings.py配置文件中默認沒有 APPEND_SLASH 這個參數,但 Django 默認這個參數爲 APPEND_SLASH = True。 其做用就是自動在網址結尾加'/'。

補充說明

是否開啓URL訪問地址後面不爲/跳轉至帶有/的路徑的配置項

APPEND_SLASH=True

例:

from django.conf.urls import url

from app01 import views

 

urlpatterns = [

        url(r'^blog/$', views.blog),

]

                                                    

5.4 分組命名匹配

語法:

(?P<name>pattern)

name是組的名稱

pattern是要匹配的模式。

例:

from django.conf.urls import url

 

from . import views

 

urlpatterns = [

    url(r'^articles/2003/$', views.special_case_2003),

    #0到9數字中匹配4個數字

    url(r'^articles/(?P<year>[0-9]{4})/$', views.year_archive),

    url(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/$', views.month_archive),

    url(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/(?P<day>[0-9]{2})/$', views.article_detail),

]

這個實現與前面的示例徹底相同,只有一個細微的差異:捕獲的值做爲關鍵字參數而不是位置參數傳遞給視圖函數。

例如,針對url /articles/2017/12/至關於按如下方式調用視圖函數:

views.month_archive(request, year="2017", month="12")

5.4.1 位置參數

urls.py

url(r'edit_publisher/(\d+)/$',views.edit_publisher),

html

    <p>

        id號:

        <input type="text" name="nid" value="{{ pub_obj.nid }}" >

    </p>

    <p>

        姓名:

        <input type="text" name="publisher_name" value="{{ pub_obj.name}}">

    </p>

views.py

def edit_publisher(request,nid):

    # nid = request.POST.get('nid')

    # 獲取編輯的對象

    if request.method == 'POST':

        publisher_name = request.POST.get('publisher_name')

        pub_obj = models.Publisher.objects.get(nid=nid)

        pub_obj.name = publisher_name

        # 向數據庫提交

        pub_obj.save()

        return redirect('/publisher_list/')

    # nid = request.GET.get('id')

    pub_obj = models.Publisher.objects.get(nid=nid)

    return render(request, 'edit_publisher.html', {'pub_obj': pub_obj})

 

頁面訪問:

 

5.4.2 關鍵字參數(命名分組)

urls.py

  url(r'edit_publisher/(?P<pk>\d+)/$',views.edit_publisher),

views.py

def edit_publisher(request,pk):

    # nid = request.POST.get('nid')

    # 獲取編輯的對象

    if request.method == 'POST':

        publisher_name = request.POST.get('publisher_name')

        pub_obj = models.Publisher.objects.get(nid=pk)

        pub_obj.name = publisher_name

        # 向數據庫提交

        pub_obj.save()

        return redirect('/publisher_list/')

    # nid = request.GET.get('id')

    pub_obj = models.Publisher.objects.get(nid=pk)

    return render(request, 'edit_publisher.html', {'pub_obj': pub_obj})

 

瀏覽器訪問:

 

5.4.3 視圖分組(分頁寫法)

urls.py

from django.conf.urls import url

from . import views

 

urlpatterns = [

url(r'^blog/$,views.page),

url(r'^blog/page(?P<num>[0-9]+)/$',views.page)

]

views.py中能夠爲num指定默認值

#

def page(request,num="10"):

pass

 

5.4.4 規範url路由分發

解釋:協同開發的做用,定義項目url保持編寫規範

 

APP01項目目錄中創建urls.py

#將原有項目的url移至app01.urls下

app01.urls.py

from django.conf.urls import url

from django.contrib import admin

from app01 import views

 

# 定義URL和函數的對應關係

urlpatterns = [

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

    url(r'^index/home', views.home),

    url(r'^index/$',views.index),

    url(r'^login/$',views.login),

    # url(r'^index/(?P<pk>\d+)/$',views.publisher_list),

    url(r'^publisher_list/$',views.publisher_list),

    url(r'add_publisher',views.add_publisher),

    url(r'del_publisher',views.del_publisher),

    url(r'edit_publisher/(?P<pk>\d+)/$',views.edit_publisher),

    # url(r'edit_publisher',views.edit_publisher),

]

 

#主urls.py

from django.conf.urls import url,include

from django.contrib import admin

# 定義URL和函數的對應關係

urlpatterns = [

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

    url(r'app01', include('app01.urls')),

 

  ]

瀏覽器訪問:

 

 

5.4.5 給視圖參數傳遞額外的參數

URLconfs 具備一個鉤子,讓你傳遞一個Python 字典做爲額外的參數傳遞給視圖函數。

django.conf.urls.url() 能夠接收一個可選的第三個參數,它是一個字典,表示想要傳遞給視圖函數的額外關鍵字參數。

 

例如:

from django.conf.urls import url

from . import views

 

urlpatterns = [

    url(r'^blog/(?P<year>[0-9]{4})/$', views.year_archive, {'foo': 'bar'}),

]

在這個例子中,對於/blog/2005/請求,Django 將調用views.year_archive(request, year='2005', foo='bar')。

當傳遞額外參數的字典中的參數和URL中捕獲值的命名關鍵字參數同名時,函數調用時將使用的是字典中的參數,而不是URL中捕獲的參數。

5.5 url命名和反向解析(重)

解釋:給url起了一個名字,用的時候能夠直接解析到地址

5.5.1 靜態傳參

語法:

1)定義url : name= 'add'

urlpatterns = [

    url(r'index/home',views.home),

    url(r'index/$',views.index),

    url(r'login/$',views.login),

    url(r'publisher_list/$',views.publisher_list,name='publisher'),

    url(r'publisher_list/add_publisher/$',views.add_publisher,name='add'),

    url(r'publisher_list/del_publisher/$',views.del_publisher),

    url(r'publisher_list/edit_publisher/$',views.edit_publisher),

]

 

2)更改模板變量 {% url 'add' %}

    <thead>

        <tr class="active  text-center" id="tr">

            <td>用戶順序</td>

            <td>用戶_ID</td>

            <td>用戶名</td>

            <td>密碼</td>

             <td>操做管理</td>

        </tr>

    </thead>

     <tbody class="text-center" >

   #原始調用

    #<a type="button" class="btn btn-success " href="/add_publisher/">增長新成員</a>

      <a type="button" class="btn btn-success " href="{%  url 'add' %}">增長新成員</a>

        {% for i  in pub %}

            <tr >

                <td class="info" >{{ forloop.counter }}</td>

                <td class="success">{{ i.nid }}</td>

                <td class="warning">{{ i.name}}</td>

                <td class="warning">{{ i.password}}</td>

                <td><a type="button" class="btn btn-danger bg-primary text-primary" href="/del_publisher/?id={{ i.nid }}"><button>刪除</button></a>

                <a type="button"  class="btn btn-warning text-primary bg-primary " href=" /edit_publisher/?id={{ i.nid }}"><button>編輯</button></a></td>

            </tr>

        {% endfor %}

     </tbody>

    </table>

  </div>

  </div>

 

3)修改views.py :  reverse('別名')

 

from diango.import reverse

 

def add_publisher(request):

    err_msg = ''

    if request.method == 'POST':

        publisher_name = request.POST.get('publisher_name')

        publisher_password = md5(publisher_name,request.POST.get('publisher_password'))

        if publisher_name:

            pub_list = models.Publisher.objects.filter(name=publisher_name)

            print(pub_list)

            if pub_list:

                err_msg = '用戶名已存在'

            else:

                pub_obj = models.Publisher.objects.create(name=publisher_name,password=publisher_password)

                print(pub_obj)

                # return redirect('/publisher_list/')

                return redirect(reverse('publisher'))

        else:

            err_msg = '用戶名不能爲空'

    return render(request, 'add_publisher.html', {'err_msg': err_msg})

5.5.2 動態傳參

解釋:針對參數值爲動態多個值時

1)urls.py  (?P<pk>\d+)/$ 動態傳參

語法:

 

    url(r'publisher_list/edit_publisher/(?P<pk>\d+)/$',views.edit_publisher,name='edd'),

]

2)views.edit_publisher()

def edit_publisher(request,pk):

    #位置傳參

    # nid = request.POST.get('nid')

    # 獲取編輯的對象

    if request.method == 'POST':

        publisher_name = request.POST.get('publisher_name')

        pub_obj = models.Publisher.objects.get(nid=pk)

        pub_obj.name = publisher_name

        # 向數據庫提交

        pub_obj.save()

        return redirect(reverse('publisher'))

    # nid = request.GET.get('nid')

    pub_obj = models.Publisher.objects.get(nid=pk)

    return render(request, 'edit_publisher.html', {'pub_obj': pub_obj})

 

3)修改publisher_list.html

語法:

{% url 'edd' pk=i.nid %}"

    <thead>

        <tr class="active  text-center" id="tr">

            <td>用戶順序</td>

            <td>用戶_ID</td>

            <td>用戶名</td>

            <td>密碼</td>

             <td>操做管理</td>

        </tr>

    </thead>

     <tbody class="text-center" >

      <a type="button" class="btn btn-success " href="{%  url 'add' %}">增長新成員</a>

 

        {% for i  in pub %}

            <tr >

                <td class="info" >{{ forloop.counter }}</td>

                <td class="success">{{ i.nid }}</td>

                <td class="warning">{{ i.name}}</td>

                <td class="warning">{{ i.password}}</td>

                <td><a type="button" class="btn btn-danger bg-primary text-primary" href="/del_publisher/?id={{ i.nid }}"><button>刪除</button></a>

                <a type="button"  class="btn btn-warning text-primary bg-primary " href="{% url 'edd' pk=i.nid %}"><button>編輯</button></a></td>

            </tr>

        {% endfor %}

 

頁面訪問:

 

5.6 命名空間

解釋:不一樣業務定義url規範,避免不一樣項目之間調用衝突

5.6.1 namespace

project中的urls.py

from django.conf.urls import url, include

 

urlpatterns = [

    url(r'^app01/', include('app01.urls', namespace='app01')),

    url(r'^app02/', include('app02.urls', namespace='app02')),

]

 

appo1中的urls.py

from django.conf.urls import url

from app01 import views

 

app_name = 'app01'

urlpatterns = [

    url(r'^(?P<pk>\d+)/$', views.detail, name='detail')

]

 

此時,當兩個app中的 url名稱重複了,我反轉URL的時候就能夠經過命名空間的名稱獲得我當前的url.

語法:

'命名空間名稱:URL名稱'

模板中使用:

{% url 'app01:detail' pk=12 pp=99 %}

views中的函數中使用

v = reverse('app01:detail', kwargs={'pk':11})

 這樣即便app中URL的命名相同,我也能夠反轉獲得正確的URL了。 

第6章 djaango--視圖

6.1 視圖函數FBV

基於view函數的視圖爲FBV視圖:

# FBV版添加班級

def add_class(request):

    if request.method == "POST":

        class_name = request.POST.get("class_name")

        models.Classes.objects.create(name=class_name)

        return redirect("/class_list/")

    return render(request, "add_class.html")

6.2 視圖類CBV

語法:

基於類的視圖爲CBV視圖:

# CBV版添加班級

from django.views import View

 

 

class AddClass(View):

 

    def get(self, request):

        return render(request, "add_class.html")

 

    def post(self, request):

        class_name = request.POST.get("class_name")

        models.Classes.objects.create(name=class_name)

        return redirect("/class_list/")

注意:

使用CBV時,urls.py中也作對應的修改:

# urls.py中

url(r'^add_class/$', views.AddClass.as_view()),

6.2.1 View模塊

寫類以前pytho提供了一個類的模塊View

6.2.2 .as_view()方法

解釋:與FBV不一樣的是,CBV定義urls.py的方法以下:

# urls.py中

url(r'^add_class/$', views.AddClass.as_view()),

6.3 裝飾器

6.3.1 FBV裝飾器

def wrapper(func):

    def inner(*args, **kwargs):

        start_time = time.time()

        ret = func(*args, **kwargs)

        end_time = time.time()

        print("used:", end_time-start_time)

        return ret

    return inner

 

# FBV版添加班級

@wrapper

def add_class(request):

    if request.method == "POST":

        class_name = request.POST.get("class_name")

        models.Classes.objects.create(name=class_name)

        return redirect("/class_list/")

    return render(request, "add_class.html")

6.3.2 CBV裝飾器

6.3.3 介紹

類中的方法與獨立函數不徹底相同,所以不能直接將函數裝飾器應用於類中的方法 ,咱們須要先將其轉換爲方法裝飾器。

6.3.4 method_decorator模塊

Django中提供了method_decorator裝飾器用於將函數裝飾器轉換爲方法裝飾器。

# CBV版添加班級

from django.views import View

from django.utils.decorators import method_decorator

 

class AddClass(View):

 

    @method_decorator(wrapper)

    def get(self, request):

        return render(request, "add_class.html")

 

    def post(self, request):

        class_name = request.POST.get("class_name")

        models.Classes.objects.create(name=class_name)

        return redirect("/class_list/")

6.3.5 擴展

# 使用CBV時要注意,請求過來後會先執行dispatch()這個方法,若是須要批量對具體的請求處理方法,如get,post等作一些操做的時候,這裏咱們能夠手動改寫dispatch方法,這個dispatch方法就和在FBV上加裝飾器的效果同樣。

 

class Login(View):

    

    def dispatch(self, request, *args, **kwargs):

        print('before')

        obj = super(Login,self).dispatch(request, *args, **kwargs)

        print('after')

        return obj

 

    def get(self,request):

        return render(request,'login.html')

 

    def post(self,request):

        print(request.POST.get('user'))

        return HttpResponse('Login.post')

6.3.6 CBV裝飾器的三種方法

模塊倒入method_decorator

    from django.utils.decorators import method_decorator

 

def timer(func):

    def inner(request, *args, **kwargs):

        now = time.time()

        ret = func(request, *args, **kwargs)

        print("函數執行時間是{}".format(time.time() - now))

        return ret

 

    return inner

 

6.3.7 方法一:直接加載方法上面

 

class AddPublisher(View):

    # http_method_names = ['get']

    def dispatch(self, request, *args, **kwargs):

        ret = super().dispatch(request, *args, **kwargs)

        return ret

    @method_decorator(timer)

    def get(self, request):

        return render(request, 'publisher_add.html')

    def post(self, request):

        print(request.body)

        new_name = self.request.POST.get('name')

        models.Publisher.objects.create(name=new_name)

        return redirect(reverse('app01:publisher'))

6.3.8 方法二:加在dispatch方法上面

class AddPublisher(View):

    # 只須要加一條就能夠同時獲取get和POST最方便

    @method_decorator(timer)

    def dispatch(self, request, *args, **kwargs):

        ret = super().dispatch(request, *args, **kwargs)

        return ret

    def get(self, request):

        return render(request, 'publisher_add.html')

    def post(self, request):

        print(request.body)

        new_name = self.request.POST.get('name')

        models.Publisher.objects.create(name=new_name)

        return redirect(reverse('app01:publisher'))

6.3.9 方法三:加在類上

 

 

@method_decorator(timer,name='post')

@method_decorator(timer,name='get')

class AddPublisher(View):

    # http_method_names = ['get']

    @method_decorator(timer)

    def dispatch(self, request, *args, **kwargs):

        ret = super().dispatch(request, *args, **kwargs)

        return ret

    def get(self, request):

        return render(request, 'publisher_add.html')

    def post(self, request):

        print(request.body)

        new_name = self.request.POST.get('name')

        models.Publisher.objects.create(name=new_name)

        return redirect(reverse('app01:publisher'))

 

6.4 request相關參數

6.4.1 path_info    

返回用戶訪問url,不包括域名

6.4.2 method       

請求中使用的HTTP方法的字符串表示,全大寫表示。

6.4.3 GET             

包含全部HTTP  GET參數的類字典對象

6.4.4 POST          

包含全部HTTP POST參數的類字典對象

6.4.5 body           

請求體,byte類型 request.POST的數據就是從body裏面提取到的

 

6.5 屬性

屬性:

  django將請求報文中的請求行、頭部信息、內容主體封裝成 HttpRequest 類中的屬性。

   除了特殊說明的以外,其餘均爲只讀的。

6.5.1 HttpRequest.scheme

   表示請求方案的字符串(一般爲http或https)

6.5.2 HttpRequest.body

  一個字符串,表明請求報文的主體。在處理非 HTTP 形式的報文時很是有用,例如:二進制圖片、XML,Json等。可是,若是要處理表單數據的時候,推薦仍是使用 HttpRequest.POST 。

另外,咱們還能夠用 python 的類文件方法去操做它,詳情參考 HttpRequest.read() 。

6.5.3 HttpRequest.path

  一個字符串,表示請求的路徑組件(不含域名)。

  例如:"/music/bands/the_beatles/"

6.5.4 HttpRequest.method

  一個字符串,表示請求使用的HTTP 方法。必須使用大寫。

  例如:"GET"、"POST"

6.5.5 HttpRequest.encoding

  一個字符串,表示提交的數據的編碼方式(若是爲 None 則表示使用 DEFAULT_CHARSET 的設置,默認爲 'utf-8')。

   這個屬性是可寫的,你能夠修改它來修改訪問表單數據使用的編碼。

   接下來對屬性的任何訪問(例如從 GET 或 POST 中讀取數據)將使用新的 encoding 值。

   若是你知道表單數據的編碼不是 DEFAULT_CHARSET ,則使用它。

6.5.6 HttpRequest.GET

  一個相似於字典的對象,包含 HTTP GET 的全部參數。詳情請參考 QueryDict 對象。

6.5.7 6.HttpRequest.POST

  一個相似於字典的對象,若是請求中包含表單數據,則將這些數據封裝成 QueryDict 對象。

  POST 請求能夠帶有空的 POST 字典 —— 若是經過 HTTP POST 方法發送一個表單,可是表單中沒有任何的數據,QueryDict 對象依然會被建立。

   所以,不該該使用 if request.POST  來檢查使用的是不是POST 方法;應該使用 if request.method == "POST"

  另外:若是使用 POST 上傳文件的話,文件信息將包含在 FILES 屬性中。

6.5.8  HttpRequest.COOKIES

  一個標準的Python 字典,包含全部的cookie。鍵和值都爲字符串。

6.5.9 HttpRequest.FILES

  一個相似於字典的對象,包含全部的上傳文件信息。

   FILES 中的每一個鍵爲<input type="file" name="" /> 中的name,值則爲對應的數據。

  注意,FILES 只有在請求的方法爲POST 且提交的<form> 帶有enctype="multipart/form-data" 的狀況下才會

   包含數據。不然,FILES 將爲一個空的相似於字典的對象。

6.5.10 HttpRequest.META

   一個標準的Python 字典,包含全部的HTTP 首部。具體的頭部信息取決於客戶端和服務器,下面是一些示例:

    CONTENT_LENGTH —— 請求的正文的長度(是一個字符串)。

    CONTENT_TYPE —— 請求的正文的MIME 類型。

    HTTP_ACCEPT —— 響應可接收的Content-Type。

    HTTP_ACCEPT_ENCODING —— 響應可接收的編碼。

    HTTP_ACCEPT_LANGUAGE —— 響應可接收的語言。

    HTTP_HOST —— 客服端發送的HTTP Host 頭部。

    HTTP_REFERER —— Referring 頁面。

    HTTP_USER_AGENT —— 客戶端的user-agent 字符串。

    QUERY_STRING —— 單個字符串形式的查詢字符串(未解析過的形式)。

    REMOTE_ADDR —— 客戶端的IP 地址。

    REMOTE_HOST —— 客戶端的主機名。

    REMOTE_USER —— 服務器認證後的用戶。

    REQUEST_METHOD —— 一個字符串,例如"GET" 或"POST"。

    SERVER_NAME —— 服務器的主機名。

    SERVER_PORT —— 服務器的端口(是一個字符串)。

   從上面能夠看到,除 CONTENT_LENGTH 和 CONTENT_TYPE 以外,請求中的任何 HTTP 首部轉換爲 META 的鍵時,

    都會將全部字母大寫並將鏈接符替換爲下劃線最後加上 HTTP_  前綴。

    因此,一個叫作 X-Bender 的頭部將轉換成 META 中的 HTTP_X_BENDER 鍵。

 

6.5.11 HttpRequest.user

  一個 AUTH_USER_MODEL 類型的對象,表示當前登陸的用戶。

  若是用戶當前沒有登陸,user 將設置爲 django.contrib.auth.models.AnonymousUser 的一個實例。你能夠經過 is_authenticated() 區分它們。

    例如:

    if request.user.is_authenticated():

        # Do something for logged-in users.

    else:

        # Do something for anonymous users.

   

       user 只有當Django 啓用 AuthenticationMiddleware 中間件時纔可用。

    匿名用戶

    class models.AnonymousUser

    django.contrib.auth.models.AnonymousUser 類實現了django.contrib.auth.models.User 接口,但具備下面幾個不一樣點:

    id 永遠爲None。

    username 永遠爲空字符串。

    get_username() 永遠返回空字符串。

    is_staff 和 is_superuser 永遠爲False。

    is_active 永遠爲 False。

    groups 和 user_permissions 永遠爲空。

    is_anonymous() 返回True 而不是False。

    is_authenticated() 返回False 而不是True。

    set_password()、check_password()、save() 和delete() 引起 NotImplementedError。

    New in Django 1.8:

    新增 AnonymousUser.get_username() 以更好地模擬 django.contrib.auth.models.User。

6.5.12 HttpRequest.session

   一個既可讀又可寫的相似於字典的對象,表示當前的會話。只有當Django 啓用會話的支持時纔可用。

6.6 上傳文件

view.py

from django.shortcuts import render, redirect, reverse, HttpResponse

from app01 import models

from django.views import View

 

class Upload(View):

 

    def get(self, request):

        return render(request, 'upload.html')

 

    def post(self, request):

        my_file = request.FILES.get('my_file')

        print(my_file.name)

        with open(my_file.name, 'wb') as f:

            for chunk in my_file.chunks():

                f.write(chunk)

        return HttpResponse('ok')

 

upload.html

<!DOCTYPE html>

<html lang="en">

<head>

    <meta charset="UTF-8">

    <title>Title</title>

</head>

<body>

<form action="" method="post" enctype="multipart/form-data">

 

    <input type="file" name="my_file">

    <button type="submit">提交</button>

</form>

</body>

</html>

 

urls.py

url(r'^pub/add/$', views.AddPublisher.as_view(),name='publisher_add')

6.7 response

6.7.1 介紹

與由Django自動建立的HttpRequest對象相比,HttpResponse對象是咱們的職責範圍了。咱們寫的每一個視圖都須要實例化,填充和返回一個HttpResponse。

HttpResponse類位於django.http模塊中。

6.7.2 使用方法

傳遞字符串

from django.http import HttpResponse

response = HttpResponse("Here's the text of the Web page.")

response = HttpResponse("Text only, please.", content_type="text/plain")

設置或刪除響應頭信息

response = HttpResponse()

response['Content-Type'] = 'text/html; charset=UTF-8'

del response['Content-Type']

屬性

HttpResponse.content:響應內容

HttpResponse.charset:響應內容的編碼

HttpResponse.status_code:響應的狀態碼

6.7.3 JsonResponse

JsonResponse是HttpResponse的子類,專門用來生成JSON編碼的響應。

from django.http import JsonResponse

response = JsonResponse({'foo': 'bar'})

print(response.content)

b'{"foo": "bar"}'

默認只能傳遞字典類型,若是要傳遞非字典類型須要設置一下safe關鍵字參數。

response = JsonResponse([1, 2, 3], safe=False)

 

6.7.4 render()

結合一個給定的模板和一個給定的上下文字典,並返回一個渲染後的 HttpResponse 對象。

 

參數:

 

l  request: 用於生成響應的請求對象。

l  template_name:要使用的模板的完整名稱,可選的參數

l  context:添加到模板上下文的一個字典。默認是一個空字典。若是字典中的某個值是可調用的,視圖將在渲染模板以前調用它。

l  content_type:生成的文檔要使用的MIME類型。默認爲 DEFAULT_CONTENT_TYPE 設置的值。默認爲'text/html'

l  status:響應的狀態碼。默認爲200。

l  useing: 用於加載模板的模板引擎的名稱。

 

例:

from django.shortcuts import render

 

def my_view(request):

    # 視圖的代碼寫在這裏

    return render(request, 'myapp/index.html', {'foo': 'bar'})

等價於

from django.http import HttpResponse

from django.template import loader

 

def my_view(request):

    # 視圖代碼寫在這裏

    t = loader.get_template('myapp/index.html')

    c = {'foo': 'bar'}

    return HttpResponse(t.render(c, request))

6.7.5 redirect()

參數能夠是:

 

l  一個模型:將調用模型的get_absolute_url() 函數

l  一個視圖,能夠帶有參數:將使用urlresolvers.reverse 來反向解析名稱

l  一個絕對的或相對的URL,將原封不動的做爲重定向的位置。

l  默認返回一個臨時的重定向;傳遞permanent=True 能夠返回一個永久的重定向。

傳遞一個具體的ORM對象(瞭解便可)

 

將調用具體ORM對象的get_absolute_url() 方法來獲取重定向的URL:

 

from django.shortcuts import redirect

 

def my_view(request):

    ...

    object = MyModel.objects.get(...)

    return redirect(object)

傳遞一個視圖的名稱

 

def my_view(request):

    ...

    return redirect('some-view-name', foo='bar')

傳遞要重定向到的一個具體的網址

 

def my_view(request):

    ...

    return redirect('/some/url/')

固然也能夠是一個完整的網址

 

def my_view(request):

    ...

    return redirect('http://example.com/')

默認狀況下,redirect() 返回一個臨時重定向。以上全部的形式都接收一個permanent 參數;若是設置爲True,將返回一個永久的重定向:

 

def my_view(request):

    ...

    object = MyModel.objects.get(...)

    return redirect(object, permanent=True)  

 

前端交互

 

 

 

自帶

 

 

區別

 

 

建議直接用json格式少一步反序列化

6.7.6 設定json

 

 

第7章 模板引擎

7.1 經常使用語法

Django模板中只須要記兩種特殊符號:

{{  }}和 {% %}

{{ }}表示變量,在模板渲染的時候替換成值,{% %}表示邏輯相關的操做。

7.2 變量

{{ 變量名 }}

變量名由字母數字和下劃線組成。

點(.)在模板語言中有特殊的含義,用來獲取對象的相應屬性值。

7.2.1 例

view中的代碼

def template_test(request):

    l = [11, 22, 33]

    d = {"name": "alex"}

 

    class Person(object):

        def __init__(self, name, age):

            self.name = name

            self.age = age

 

        def dream(self):

            return "{} is dream...".format(self.name)

 

    Alex = Person(name="Alex", age=34)

    Egon = Person(name="Egon", age=9000)

    Eva_J = Person(name="Eva_J", age=18)

 

    person_list = [Alex, Egon, Eva_J]

    return render(request, "template_test.html", {"l": l, "d": d, "person_list": person_list})

模板中支持的寫法:

{# 取l中的第一個參數 #}

{{ l.0 }}

{# 取字典中key的值 #}

{{ d.name }}

{# 取對象的name屬性 #}

{{ person_list.0.name }}

{# .操做只能調用不帶參數的方法 #}

{{ person_list.0.dream }}

注:當模板系統遇到一個(.)時,會按照以下的順序去查詢:

在字典中查詢

屬性或者方法

數字索引

7.3 Filters

翻譯爲過濾器,用來修改變量的顯示結果。

語法: {{ value|filter_name:參數 }}

'|'左右沒有空格沒有空格沒有空格

7.3.1 default 

{{ value|default:"nothing"}}

若是value值沒傳的話就顯示nothing

注:TEMPLATES的OPTIONS能夠增長一個選項:string_if_invalid:'找不到',能夠替代default的的做用。

7.3.2 filesizeformat

將值格式化爲一個 「人類可讀的」 文件尺寸 (例如 '13 KB', '4.1 MB', '102 bytes', 等等)。例如:

{{ value|filesizeformat }}

若是 value 是 123456789,輸出將會是 117.7 MB。

7.3.3 add

給變量加參數

{{ value|add:"2" }}

value是數字4,則輸出結果爲6。

{{ first|add:second }}

若是first是 [1,.2,3] ,second是 [4,5,6] ,那輸出結果是 [1,2,3,4,5,6] 。

7.3.4 lower

小寫

{{ value|lower }}

upper

大寫

{{ value|upper}}

7.3.5 title

標題

{{ value|title }}

ljust

左對齊

"{{ value|ljust:"10" }}"

rjust

右對齊

"{{ value|rjust:"10" }}"

center

居中

"{{ value|center:"15" }}"

7.3.6 length

{{ value|length }}

返回value的長度,如 value=['a', 'b', 'c', 'd']的話,就顯示4.

7.3.7 slice  

切片

{{value|slice:"2:-1"}}

7.3.8 first

取第一個元素

{{ value|first }}

7.3.9 last

取最後一個元素

{{ value|last }}

7.3.10 join

使用字符串拼接列表。同python的str.join(list)。

{{ value|join:" // " }}

7.3.11 truncatechars

若是字符串字符多於指定的字符數量,那麼會被截斷。截斷的字符串將以可翻譯的省略號序列(「...」)結尾。

參數:截斷的字符數

{{ value|truncatechars:9}}

7.3.12 date

日期格式化

{{ value|date:"Y-m-d H:i:s"}}

可格式化輸出的字符:點擊查看。

7.3.13 safe

Django的模板中會對HTML標籤和JS等語法標籤進行自動轉義,緣由顯而易見,這樣是爲了安全。可是有的時候咱們可能不但願這些HTML元素被轉義,好比咱們作一個內容管理系統,後臺添加的文章中是通過修飾的,這些修飾多是經過一個相似於FCKeditor編輯加註了HTML修飾符的文本,若是自動轉義的話顯示的就是保護HTML標籤的源文件。爲了在Django中關閉HTML的自動轉義有兩種方式,若是是一個單獨的變量咱們能夠經過過濾器「|safe」的方式告訴Django這段代碼是安全的沒必要轉義。

好比:

 

value = "<a href='#'>點我</a>"

 

{{ value|safe}}

 

 

時間格式全局化

 

7.3.14 自定義filter

自定義過濾器只是帶有一個或兩個參數的Python函數:

 

n  變量(輸入)的值 - -不必定是一個字符串

n  參數的值 - 這能夠有一個默認值,或徹底省略

例如,在過濾器{{var | foo:「bar」}}中,過濾器foo將傳遞變量var和參數「bar」。

 

自定義filter代碼文件擺放位置:

app01/

    __init__.py

    models.py

    templatetags/  # 在app01下面新建一個package package

        __init__.py

        app01_filters.py  # 建一個存放自定義filter的py文件

    views.py

編寫自定義filter

from django import template

register = template.Library()

 

@register.filter

def fill(value, arg):

    return value.replace(" ", arg)

 

 

@register.filter(name="addSB")

def add_sb(value):

    return "{} SB".format(value)

使用自定義filter

{# 先導入咱們自定義filter那個文件 #}

{% load app01_filters %}

 

{# 使用咱們自定義的filter #}

{{ somevariable|fill:"__" }}

{{ d.name|addSB }}

 

7.3.15 for

<ul>

{% for user in user_list %}

    <li>{{ user.name }}</li>

{% endfor %}

</ul>

for循環可用的一些參數:

Variable    Description

forloop.counter 當前循環的索引值(從1開始)

forloop.counter0    當前循環的索引值(從0開始)

forloop.revcounter  當前循環的倒序索引值(從1開始)

forloop.revcounter0 當前循環的倒序索引值(從0開始)

forloop.first   當前循環是否是第一次循環(布爾值)

forloop.last    當前循環是否是最後一次循環(布爾值)

forloop.parentloop  本層循環的外層循環

for ... empty

<ul>

{% for user in user_list %}

    <li>{{ user.name }}</li>

{% empty %}

    <li>空空如也</li>

{% endfor %}

</ul>

if,elif和else

{% if user_list %}

  用戶人數:{{ user_list|length }}

{% elif black_list %}

  黑名單數:{{ black_list|length }}

{% else %}

  沒有用戶

{% endif %}

固然也能夠只有if和else

{% if user_list|length > 5 %}

  七座豪華SUV

{% else %}

    黃包車

{% endif %}

if語句支持 and 、or、==、>、<、!=、<=、>=、in、not in、is、is not判斷。

 

7.3.16 with

定義一箇中間變量

{% with total=business.employees.count %}

    {{ total }} employee{{ total|pluralize }}

{% endwith %}

csrf_token

這個標籤用於跨站請求僞造保護。

在頁面的form表單裏面寫上{% csrf_token %}

7.3.17 註釋

{# ... #}

7.3.18 注意事項

1. Django的模板語言不支持連續判斷,即不支持如下寫法:

{% if a > b > c %}

...

{% endif %}

2. Django的模板語言中屬性的優先級大於方法

def xx(request):

    d = {"a": 1, "b": 2, "c": 3, "items": "100"}

    return render(request, "xx.html", {"data": d})

如上,咱們在使用render方法渲染一個頁面的時候,傳的字典d有一個key是items而且還有默認的 d.items() 方法,此時在模板語言中:

{{ data.items }}

默認會取d的items key的值。

 

7.4 模板繼承

母板

<!DOCTYPE html>

<html lang="en">

<head>

  <meta charset="UTF-8">

  <meta http-equiv="x-ua-compatible" content="IE=edge">

  <meta name="viewport" content="width=device-width, initial-scale=1">

  <title>Title</title>

  {% block page-css %}

 

  {% endblock %}

</head>

<body>

 

<h1>這是母板的標題</h1>

 

{% block page-main %}

 

{% endblock %}

<h1>母板底部內容</h1>

{% block page-js %}

 

{% endblock %}

</body>

</html>

注意:咱們一般會在母板中定義頁面專用的CSS塊和JS塊,方便子頁面替換。

繼承母板

在子頁面中在頁面最上方使用下面的語法來繼承母板。

{% extends 'layouts.html' %}

7.4.1 塊(block)

經過在母板中使用{% block  xxx %}來定義"塊"。

在子頁面中經過定義母板中的block名來對應替換母板中相應的內容。

{% block page-main %}

  <p>世情薄</p>

  <p>人情惡</p>

  <p>雨送黃昏花易落</p>

{% endblock %}

7.4.2 組件

能夠將經常使用的頁面內容如導航條,頁尾信息等組件保存在單獨的文件中,而後在須要使用的地方按以下語法導入便可。

{% include 'navbar.html' %}

靜態文件相關

{% load static %}

<img src="{% static "images/hi.jpg" %}" alt="Hi!" />

引用JS文件時使用:

{% load static %}

<script src="{% static "mytest.js" %}"></script>

某個文件多處被用到能夠存爲一個變量

{% load static %}

{% static "images/hi.jpg" as myphoto %}

<img src="{{ myphoto }}"></img>

使用get_static_prefix

{% load static %}

<img src="{% get_static_prefix %}images/hi.jpg" alt="Hi!" />

或者

{% load static %}

{% get_static_prefix as STATIC_PREFIX %}

<img src="{{ STATIC_PREFIX }}images/hi.jpg" alt="Hi!" />

<img src="{{ STATIC_PREFIX }}images/hi2.jpg" alt="Hello!" />

7.4.3 自定義simpletag

和自定義filter相似,只不過接收更靈活的參數。

定義註冊simple tag

@register.simple_tag(name="plus")

def plus(a, b, c):

    return "{} + {} + {}".format(a, b, c)

使用自定義simple tag

{% load app01_demo %}

{# simple tag #}

{% plus "1" "2" "abc" %}

inclusion_tag

 

 

示例:

7.4.4 templatetags/my_inclusion.py

 

from django import template

register = template.Library()

 

@register.inclusion_tag('result.html')

def show_results(n):

    n = 1 if n < 1 else int(n)

    data = ["第{}項".format(i) for i in range(1, n+1)]

    return {"data": data}

7.4.5 templates/result.html

<ul>

  {% for choice in data %}

    <li>{{ choice }}</li>

  {% endfor %}

</ul>

7.4.6 templates/index.html

<!DOCTYPE html>

<html lang="en">

<head>

  <meta charset="UTF-8">

  <meta http-equiv="x-ua-compatible" content="IE=edge">

  <meta name="viewport" content="width=device-width, initial-scale=1">

  <title>inclusion_tag test</title>

</head>

<body>

 

{% load my_inclusion %}

 

{% show_results 10 %}

</body>

</html>

7.5 bootstrip沒有數據優化

  {% empty %}

 

    <h2 class="sub-header">用戶管理列表</h2>    <a class="btn btn-success" href="{% url 'app01:manage_add' %}">添加</a>    <div class="table-responsive">        <table class="table table-bordered table-hover">            <thead>            <tr>                <th>number</th>                <th>ID</th>                <th>name</th>                <th>password</th>                <th>操做</th>            </tr>            </thead>            <tbody>            {% for server in server %}                <tr>                    <td>{{ forloop.counter }}</td>                    <td>{{ server.id }}</td>                    <td>{{ server.name }}</td>                    <td>{{ server.password}}</td>                    <td>                        <a class="btn btn-success btn-sm"                           href="">編輯</a>                        <a class="btn btn-danger btn-sm" href="{% url 'app01:manage_del' pk=server.id %}">刪除</a>                    </td>                </tr>            {% empty %}                <tr>                    <td colspan="4" style="text-align: center">沒有數據</td>                </tr>            {% endfor %}            </tbody>        </table>    </div>{% endblock %}
相關文章
相關標籤/搜索