django 1

 

 1. Django的命令:css

1. 下載安裝
pip install django==1.11.16 -i 源

2. 建立項目
django-admin startproject 項目名稱

3. 啓動項目
cd 項目根目錄下
python manage.py runserver # 127.0.0.1:8000
python manage.py runserver 80 # 127.0.0.1:80
python manage.py runserver 0.0.0.0:80 # 0.0.0.0:80 

4. 建立APP
python manage.py startapp app名稱

註冊
5. 數據庫相關
python manage.py makemigrations # 記錄model的變動狀況
python manage.py migrate # 將變動記錄同步到數據庫中html

Django 的路由系統 

URL配置(URLconf)就像Django所支撐網站的目錄。它的本質是URL與要爲該URL調用的視圖函 數之間的映射表。前端

咱們就是以這種方式告訴Django,遇到哪一個URL的時候,要對應執行哪一個函數。python

基本格式

from django.conf.urls import url
from app1 import views as aap1vw
from app2 import views as aap2vw
urlpatterns
= [ url(正則表達式, app1vw,參數,別名),
   url(正則表達式, app2vw, 參數, 別名), ]

示例:web

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),
]

Django 2.0版本中的路由系統是下面的寫法(官方文檔):正則表達式

複製代碼
from django.urls import path,re_path

urlpatterns = [
    path('articles/2003/', views.special_case_2003),         #與1的區別一個是url 一個是path
    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),
]
複製代碼

正則匹配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),
]

注意事項 

  1. urlpatterns中的元素按照書寫順序從上往下逐一匹配正則表達式,一旦匹配成功則再也不繼續。 
  2. 若要從URL中捕獲一個值,只須要在它周圍放置一對圓括號(分組匹配)。
  3. 不須要添加一個前導的反斜槓,由於每一個URL 都有。例如,應該是^articles 而不是 ^/articles。
  4. 每一個正則表達式前面的'r' 是可選的可是建議加上。

 

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

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

其效果就是:django

咱們定義了urls.py:json

from django.conf.urls import url
from app01 import views

urlpatterns = [
    url(r'^blog/$', views.blog),
]

訪問 http://www.example.com/blog 時,默認將網址自動轉換爲 http://www.example/com/blog/ 。bootstrap

若是在settings.py中設置了 APPEND_SLASH=False,此時咱們再請求 http://www.example.com/blog 時就會提示找不到頁面。

 分組命名匹配

上面的示例使用簡單的正則表達式分組匹配(經過圓括號)來捕獲URL中的值並以位置參數形式傳遞給視圖。

在更高級的用法中,可使用分組命名匹配的正則表達式組來捕獲URL中的值並以關鍵字參數形式傳遞給視圖。

在Python的正則表達式中,分組命名正則表達式組的語法是(?P<name>pattern),其中name是組的名稱,pattern是要匹配的模式。

下面是以上URLconf 使用命名組的重寫:

複製代碼
from django.conf.urls import url

from . import views
#將匹配到括號裏的url內容傳給views,views必須的寫形參接收
urlpatterns = [
    url(r'^articles/2003/$', views.special_case_2003),
    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")        #viewa必須的帶接收的參數

在實際應用中,使用分組命名匹配的方式可讓你的URLconf 更加明晰且不容易產生參數順序問題的錯誤,可是有些開發人員則認爲分組命名組語法太醜陋、繁瑣。

至於究竟應該使用哪種,你能夠根據本身的喜愛來決定。

視圖函數中指定默認值

# urls.py中
from django.conf.urls import url

from . import views

urlpatterns = [                        #不一樣的url找同一個視圖函數
    url(r'^blog/$', views.page),
    url(r'^blog/page(?P<num>[0-9]+)/$', views.page),  
]

# views.py中,能夠爲num指定默認值
def page(request, num="1"):
    pass

在上面的例子中,兩個URL模式指向相同的view - views.page - 可是第一個模式並無從URL中捕獲任何東西。

若是第一個模式匹配上了,page()函數將使用其默認參數num=「1」,若是第二個模式匹配,page()將使用正則表達式捕獲到的num值。

 

include使urls.py 文件放在本身app目錄裏

將django項目裏的urls.py 文件複製到app1 和app2裏

項目裏的urls.py文件

from django.conf.urls import url, include #引用include 
urlpatterns = [
    url(r'app1/', include('app1.urls')),      #r''能夠爲空,也能夠匹配1級url,include 找到app1裏的urls文件
    url(r'app1/', include('app1.urls')),
    url(r'app2/', include('app2.urls')),
    url(r'app2/', include('app2.urls')),
    url(r'app2/', include('app2.urls')),
    ]

app1裏的urls.py文件

from django.conf.urls import url
from app1 import views as aap1vw

urlpatterns = [
    #此時的url前邊要加上/app1/ 即127.0.0.1/app1/zzzz/       
    url(r'zzzz/',aap1vw.zzzz),

app2裏的urls.py文件

from django.conf.urls import url

from app2 import views as aap2vw

urlpatterns = [
    url(r'xxxx/',aap2vw.xxxx),
    url(r'dddd/',aap2vw.dddd),
    url(r'cccc/',aap2vw.cccc),
]

 使用上述方法會致使 html頁面裏的和views裏寫死的url不能使用,解決辦法:給url命名和反向解析:

url命名和反向解析

  給url起一個別名   經過反向解析,經過別名動態拿到url地址

在app1裏的urls.py文件裏給url地址起別名

from django.conf.urls import url
from app1 import views as aap1vw

urlpatterns = [
    url(r'zhanshi/',aap1vw.Zhan_shi,name='zhanshi'),     #增長別名
    url(r'add/', aap1vw.Add,name='add'), 
    url(r'update/', aap1vw.Update,name='update'),
    url(r'del/', aap1vw.Del,name='del'),
]

修改html展現頁裏的url,使用url別名   模板:  {% url '別名' %}

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="/static/css/bootstrap.min.css">
    <link rel="stylesheet" href="/static/css/das.css">
</head>
<body>

<nav class="navbar navbar-inverse navbar-fixed-top">
    <div class="container-fluid">
        <div class="navbar-header">
            <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar"
                    aria-expanded="false" aria-controls="navbar">
                <span class="sr-only">Toggle navigation</span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
            </button>
            <a class="navbar-brand" href="#">出版社管理</a>
        </div>
        <div id="navbar" class="navbar-collapse collapse">
            <ul class="nav navbar-nav navbar-right">
                <li><a href="#">Dashboard</a></li>
                <li><a href="#">Settings</a></li>
                <li><a href="#">Profile</a></li>
                <li><a href="#">Help</a></li>
            </ul>
            <form class="navbar-form navbar-right">
                <input type="text" class="form-control" placeholder="Search...">
            </form>
        </div>
    </div>
</nav>

<div class="container-fluid">
    <div class="row">
        <div class="col-sm-3 col-md-2 sidebar">
            <ul class="nav nav-sidebar"> 
                <li class="active"><a href="{% url 'zhanshi' %}">出版社列表 <span class="sr-only">(current)</span></a></li>       {#將 以前的/展現/ 改成 {% url 'zhanshi' %}#} 動態或其url別名對應的url路徑
            </ul>
        </div>
        <div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main">
            <h2 class="sub-header">出版社信息</h2>
            <div class="table-responsive">
            <a href="{% url 'add' %}" class="btn btn-primary">添加</a>
                <table class="table table-striped table-hover">
                    <thead>
                    <tr>
                        <th>序號<th>
                        <th>ID</th>
                        <th>出版社名稱</th>
                        <th>操做</th>
                    </tr>
                    </thead>
                    <tbody>
                    {% for foo in all %}
                        <tr>
                            <td>{{ forloop.counter }}</td>
                            <td>{{ foo.pk }}</td>
                            <td>{{ foo.mane }}</td>
                            <td>
                                <a href="{% url 'del' %}?sh={{ foo.pk }}" class="btn btn-danger btn-sm">刪除</a>
                                <a href="{% url 'update' %}?zj={{ foo.pk }}" class="btn btn-primary btn-sm">編輯</a>
                            </td>
                        </tr>
                    {% endfor %}
                    </tbody>
                </table>
            </div>
        </div>
    </div>
</div>

</body>
</html>

修改views.py 裏寫死的redirect 跳轉的url .(須要在引用reverse方法)   模板   reverse('別名')

from django.shortcuts import render,redirect,reverse     #引用reverse方法
from app1 import models

def Zhan_shi(request):
    all_tusu = models.tusu.objects.all()
    return render(request,'zhanshi.html',{'all': all_tusu})
def Add(request):
    if request.method == 'POST':
        newname = request.POST.get('newname')
        models.tusu.objects.create(mane=newname)
        return redirect(reverse('zhanshi'))                     #將以前寫的跳轉寫死的redirect('/zhanshi/') 修改成獲取別名的redirect(reverse('zhanshi')) return render(request,'add.html')
def Update(request):
    pk = request.GET.get('zj')
    obj = models.tusu.objects.filter(pk=pk).first()
    if request.method == 'POST':
        newname = request.POST.get('newname')
        obj.mane = newname
        obj.save()
        return redirect(reverse('zhanshi'))
    return render(request,'update.html', {'obj' : obj} )
def Del(request):
    pk = request.GET.get('sh')
    obj = models.tusu.objects.filter(pk=pk).first()
    if request.method == 'POST':
        dname = request.POST.get('dname')
        models.tusu.objects.get(mane = dname).delete()
        return redirect(reverse('zhanshi'))
    return render(request,'del.html',{'obj':obj})

命名空間模式

 

用來解決 不一樣app中,url名相同路由找錯的問題

即便不一樣的APP使用相同的URL名稱,URL的命名空間模式也可讓你惟一反轉命名的URL。

設置項目裏的urls.py

from django.conf.urls import url, include

urlpatterns = [
    url(r'app1/', include('app1.urls',namespace='app1')),     #namespace 至關於增長一個別名,用來讓模板和views來識別出惟一的url路徑
    url(r'app2/', include('app2.urls',namespace='app2'))
    ]

 app1中的urls.py

from django.conf.urls import url
from app01 import views
 
app_name = 'app01'
urlpatterns = [
    url(r'^zhanshi', views.yemian1, name='zhanshi'),
    url(r'^add', views.yemian2, name='add'),       
]

 app2中的urls.py

from django.conf.urls import url
from app01 import views
 
app_name = 'app01'
urlpatterns = [
    url(r'^zhanshi', views.yemian1, name='zhanshi'),
    url(r'^add', views.yemian2, name='add'),       
]

此時app1和app2裏的別名相同,要想確認惟一頁面,就要把namespace對應的值加入到先後端代碼裏

前端使用方法

{% url 'app1:zhanshi' %}    #在app裏的url的別名前加上 views裏的url別名

後端使用方法

return redirect(reverse('app1:zhanshi')        #和前端同樣也是前面加views裏的url別名

MVC框架和MTV框架

詳細介紹:http://www.ruanyifeng.com/blog/2007/11/mvc.html

MVC,全名是Model View Controller,是軟件工程中的一種軟件架構模式,把軟件系統分爲三個基本部分:模型(Model)、視圖(View)和控制器(Controller),具備耦合性低、重用性高、生命週期成本低等優勢。

 

Django框架的設計模式借鑑了MVC框架的思想,也是分紅三部分,來下降各個部分之間的耦合性。

Django框架的不一樣之處在於它拆分的三部分爲:Model(模型)、Template(模板)和View(視圖),也就是MTV框架。

Django的MTV模式

Model(模型):負責業務對象與數據庫的對象(ORM)

Template(模版):負責如何把頁面展現給用戶

View(視圖):負責業務邏輯,並在適當的時候調用Model和Template

 此外,Django還有一個urls分發器,它的做用是將一個個URL的頁面請求分發給不一樣的view處理,view再調用相應的Model和Template

Django框架圖示

Django的View(視圖)

一個視圖函數(類),簡稱視圖,是一個簡單的Python 函數(類),它接受Web請求而且返回Web響應。

響應能夠是一張網頁的HTML內容,一個重定向,一個404錯誤,一個XML文檔,或者一張圖片。

不管視圖自己包含什麼邏輯,都要返回響應。代碼寫在哪裏也無所謂,只要它在你當前項目目錄下面。除此以外沒有更多的要求了——能夠說「沒有什麼神奇的地方」。爲了將代碼放在某處,你們約定成俗將視圖放置在項目(project)或應用程序(app)目錄中的名爲views.py的文件中。

CBV和FBV

咱們以前寫過的都是基於函數的view,就叫FBV。還能夠把view寫成基於類CBV的。

FBV (以前寫的添加出版舍)

def Add(request):               #此處定義的是函數 是FBV F是function if request.method == 'POST':
        newname = request.POST.get('newname')
        models.tusu.objects.create(mane=newname)
        return redirect(reverse('app1:zhanshi'))
    return render(request,'add.html')

CBV(C爲類,把FBV改成CBV)

先修改 對應的url

from django.conf.urls import url
from app1 import views as aap1vw

urlpatterns = [
    url(r'zhanshi/',aap1vw.Zhan_shi,name='zhanshi'),
    url(r'add1/', aap1vw.Add,name='add'),                #這是FBV的url
    url(r'add2/', aap1vw.AddC.as_view(),name='add'),     #這是CBV的url 區別在於後邊多了.as_view()
    url(r'update/', aap1vw.Update, name='update'),
    url(r'del/', aap1vw.Del,name='del'),

寫CBF方法

from django.views import View      #在VBV的基礎上增長引用View方法

class AddC(View):                  #定義類名並繼承View def get(self,request):              #與FBV的區別在於直接把get和post請求處理的邏輯區分開了 邏輯更清晰 return render(request, 'add.html')
    def post(self,request):
        newname = request.POST.get('newname')
        models.tusu.objects.create(mane=newname)
        return redirect(reverse('app1:zhanshi'))

給視圖加裝飾器

裝飾器計算程序執行時間

import time
def Time(func):
    def inner(*args, **kwargs):
        cc = time.time()
        ret = func(*args,**kwargs)
        print(cc - time.time())
        return ret
    return inner

裝飾FBV

FBV自己就是一個函數,因此和給普通的函數加裝飾器無差

@Time
def Add(request):
    if request.method == 'POST':
        newname = request.POST.get('newname')
        models.tusu.objects.create(mane=newname)
        return redirect(reverse('app1:zhanshi'))
    return render(request,'add.html')
 

裝飾CBV

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

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

第一種 low版直接在函數上加

class AddC(View):
    @Time
    def get(self,request):
        return render(request, 'add.html')
    @Time
    def post(self,request):
        newname = request.POST.get('newname')
        models.tusu.objects.create(mane=newname)
        return redirect(reverse('app1:zhanshi'))

第二種引用method_decorator

from django.utils.decorators import method_decorator      #引用method_decorator方法, 

class AddC(View): 
    @method_decorator(Time)             #在每一個函數上加裝飾器
    def get(self,request):
        return render(request, 'add.html')
    @method_decorator(Time)
    def post(self,request):
        newname = request.POST.get('newname')
        models.tusu.objects.create(mane=newname)
        return redirect(reverse('app1:zhanshi'))
 

第三種 引用上級的dispatch

from django.utils.decorators import method_decorator
#無論走post仍是gat都走dispatch函數,裝飾dispatch函數就是裝飾了他倆
class AddC(View): 
    @method_decorator(Time) #裝飾當前的dispatch函數
    def dispatch(self, request, *args, **kwargs):     #定義函數dispatch
        ret = super().dispatch(request, *args, **kwargs)  引用上級的dispatch
        return ret            #把上級的調用結果返回給當前的dispatch函數
    def get(self,request):
        return render(request, 'add.html')
    def post(self,request):
        newname = request.POST.get('newname')
        models.tusu.objects.create(mane=newname)
        return redirect(reverse('app1:zhanshi'))

第四種在類上加並指定使用裝飾器的函數

from django.utils.decorators import method_decorator
@ method_decorator(Time,name='get')
@ method_decorator(Time,name='post')
class AddC(View):
    def get(self,request):
        return render(request, 'add.html')
    def post(self,request):
        newname = request.POST.get('newname')
        models.tusu.objects.create(mane=newname)
        return redirect(reverse('app1:zhanshi'))

第五種 最終版直接裝飾上級的dispatch 一句搞定

from django.utils.decorators import method_decorator
@ method_decorator(Time,name='dispatch')
class AddC(View):
    def get(self,request):
        return render(request, 'add.html')
    def post(self,request):
        newname = request.POST.get('newname')
        models.tusu.objects.create(mane=newname)
        return redirect(reverse('app1:zhanshi'))

拓展 直接在函數上加裝飾器和引用method_decorator家裝飾器的區別

區別在於在裝飾器裏接受的args

def Time(func):
    def inner(*args, **kwargs):
        cc = time.time()
        ret = func(*args,**kwargs)
        print(cc - time.time())
        return ret
    return inner

若是直接加 args接受倆參數,第一個是func對象,第二個是request請求對象

若是用method_decorator  args 只接受一個參數就是request對象

from django.utils.decorators import method_decorator
# @ method_decorator(Time,name='dispatch')
class AddC(View):
    @Time                           #get方式直接裝飾 def get(self,request):
        return render(request, 'add.html')
    @method_decorator(Time)         #post方式method_decorator方式 def post(self,request):       
        newname = request.POST.get('newname')
        models.tusu.objects.create(mane=newname)
        return redirect(reverse('app1:zhanshi'))

結果

(<app1.views.AddC object at 0x00000241089604A8>, <WSGIRequest: GET '/app1/add2/'>)      #get方式 args倆參數 -0.0019369125366210938
[22/Feb/2019 22:44:11] "GET /app1/add2/ HTTP/1.1" 200 2628


(<WSGIRequest: POST '/app1/add2/'>,)                           #post方式 args一個參數 -0.01776266098022461
[22/Feb/2019 22:44:15] "POST /app1/add2/ HTTP/1.1" 302 0

 請求和響應request和response

請求新手必備三件套

HttpResponse('字符串')                  #給請求返回一個字符串   
redirect(request,'html文件') #給請求返回一個html文件 rende(重定向地址) #重定向

requset對象

request屬性

    request.method        請求方法 GET POST PUT

    request.GET             URL上攜帶的參數

    request.POST           POST請求提交的數據

    request.path    返回用戶訪問url路徑,不包括域名和參數信息   (和request.path_info同樣)

    request.body              請求體,byte類型,即 POST請求傳過來的參數

class AddC(View):
    @Time
    def get(self,request):
        print(request.GET)
        return render(request, 'add.html')
    @method_decorator(Time)
    def post(self,request):
        print(request.method)
        print(request.path_info)
        print(request.body)
        print(request.POST)
        newname = request.POST.get('newname')
        models.tusu.objects.create(mane=newname)
        return redirect(reverse('app1:zhanshi'))
# 打印出的參數
(<WSGIRequest: POST '/app1/add2/'>,) #url上帶的參數 request.GET 因爲沒有在get上傳參 因此這個例子沒有參數 POST    #請求方式 request.method /app1/add2/ #url路徑 request.path_info b'newname=%E4%BA%BA%E6%B0%91%E5%87%BA%E7%89%88%E7%A4%BE' #請求主體 byte請求體 request.body <QueryDict: {'newname': ['人民出版社']}> #post請求出來的鍵值, request.POST

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

def Zhan_shi(request):
    all_tusu = models.tusu.objects.all()
    print(request.scheme)
    return render(request,'zhanshi.html',{'all': all_tusu})

http

     request.FILES

一個相似於字典的對象,包含全部的上傳文件信息。 FILES 中的每一個鍵爲<input type="file" name="" /> 中的name,值則爲對應的數據。   注意,FILES 只有在請求的方法爲POST 且提交的<form> 帶有enctype="multipart/form-data" 的狀況下才會 包含數據。不然,FILES 將爲一個空的相似於字典的對象。

    request.META

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

def Zhan_shi(request):
    all_tusu = models.tusu.objects.all()
    print(request.scheme)
    print(request.META)
    return render(request,'zhanshi.html',{'all': all_tusu})

{'ALLUSERSPROFILE': 'C:\\ProgramData', 'APPDATA': 'C:\\Users\\22490\\AppData\\Roaming', 'COMMONPROGRAMFILES': 'C:\\Program Files\\Common Files', 'COMMONPROGRAMFILES(X86)': 'C:\\Program Files (x86)\\Common Files', 'COMMONPROGRAMW6432': 'C:\\Program Files\\Common Files', 'COMPUTERNAME': 'DESKTOP-G8I5SER', 'COMSPEC': 'C:\\WINDOWS\\system32\\cmd.exe', 'CONFIGSETROOT': 'C:\\WINDOWS\\ConfigSetRoot', 'DJANGO_SETTINGS_MODULE': 'tushu.settings', 'DRIVERDATA': 'C:\\Windows\\System32\\Drivers\\DriverData', 'FPS_BROWSER_APP_PROFILE_STRING': 'Internet Explorer', 'FPS_BROWSER_USER_PROFILE_STRING': 'Default', 'HOMEDRIVE': 'C:', 'HOMEPATH': '\\Users\\22490', 'LOCALAPPDATA': 'C:\\Users\\22490\\AppData\\Local', 'LOGONSERVER': '\\\\DESKTOP-G8I5SER', 'MOZ_PLUGIN_PATH': 'D:\\福喜\\Foxit Reader\\plugins\\', 'NUMBER_OF_PROCESSORS': '4', 'ONEDRIVE': 'C:\\Users\\22490\\OneDrive', 'OS': 'Windows_NT', 'PATH': 'C:\\Python27\\;C:\\Python27\\Scripts;C:\\Python36\\Scripts\\;C:\\Python36\\;C:\\Program Files (x86)\\Intel\\iCLS Client\\;C:\\Program Files\\Intel\\iCLS Client\\;C:\\Windows\\system32;C:\\Windows;C:\\Windows\\System32\\Wbem;C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\;C:\\Program Files (x86)\\Intel\\Intel(R) Management Engine Components\\DAL;C:\\Program Files\\Intel\\Intel(R) Management Engine Components\\DAL;C:\\Program Files (x86)\\Intel\\Intel(R) Management Engine Components\\IPT;C:\\Program Files\\Intel\\Intel(R) Management Engine Components\\IPT;C:\\Program Files (x86)\\NVIDIA Corporation\\PhysX\\Common;C:\\WINDOWS\\system32;C:\\WINDOWS;C:\\WINDOWS\\System32\\Wbem;C:\\WINDOWS\\System32\\WindowsPowerShell\\v1.0\\;C:\\WINDOWS\\System32\\OpenSSH\\;D:\\shexiangt\\3rdparty\\lib\\Win32\\;D:\\shexiangt\\Redist\\Win32\\;C:\\Users\\22490\\AppData\\Local\\Microsoft\\WindowsApps;;D:\\pycharm\\PyCharm 2018.3.2\\bin;;C:\\Python36\\lib\\site-packages\\numpy\\.libs;C:\\Python36\\lib\\site-packages\\numpy\\.libs', 'PATHEXT': '.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC;.PY;.PYW', 'PROCESSOR_ARCHITECTURE': 'AMD64', 'PROCESSOR_IDENTIFIER': 'Intel64 Family 6 Model 142 Stepping 9, GenuineIntel', 'PROCESSOR_LEVEL': '6', 'PROCESSOR_REVISION': '8e09', 'PROGRAMDATA': 'C:\\ProgramData', 'PROGRAMFILES': 'C:\\Program Files', 'PROGRAMFILES(X86)': 'C:\\Program Files (x86)', 'PROGRAMW6432': 'C:\\Program Files', 'PSMODULEPATH': 'C:\\Program Files\\WindowsPowerShell\\Modules;C:\\WINDOWS\\system32\\WindowsPowerShell\\v1.0\\Modules', 'PT5HOME': 'D:\\思科交換機模擬器\\Cisco Packet Tracer 6.0', 'PT6HOME': 'D:\\思科交換機模擬器\\Cisco Packet Tracer 6.0', 'PUBLIC': 'C:\\Users\\Public', 'PYCHARM': 'D:\\pycharm\\PyCharm 2018.3.2\\bin;', 'PYCHARM_HOSTED': '1', 'PYCHARM_MATPLOTLIB_PORT': '55621', 'PYTHON36': 'C:\\Python36', 'PYTHONIOENCODING': 'UTF-8', 'PYTHONPATH': 'D:\\django\\tushu;D:\\pycharm\\PyCharm 2018.3.2\\helpers\\pycharm_matplotlib_backend', 'PYTHONUNBUFFERED': '1', 'SESSIONNAME': 'Console', 'SYSTEMDRIVE': 'C:', 'SYSTEMROOT': 'C:\\WINDOWS', 'TEMP': 'C:\\Users\\22490\\AppData\\Local\\Temp', 'TMP': 'C:\\Users\\22490\\AppData\\Local\\Temp', 'USERDOMAIN': 'DESKTOP-G8I5SER', 'USERDOMAIN_ROAMINGPROFILE': 'DESKTOP-G8I5SER', 'USERNAME': '22490', 'USERPROFILE': 'C:\\Users\\22490', 'WINDIR': 'C:\\WINDOWS', 'RUN_MAIN': 'true', 'SERVER_NAME': 'DESKTOP-G8I5SER', 'GATEWAY_INTERFACE': 'CGI/1.1', 'SERVER_PORT': '8000', 'REMOTE_HOST': '', 'CONTENT_LENGTH': '', 'SCRIPT_NAME': '', 'SERVER_PROTOCOL': 'HTTP/1.1', 'SERVER_SOFTWARE': 'WSGIServer/0.2', 'REQUEST_METHOD': 'GET', 'PATH_INFO': '/app1/zhanshi/', 'QUERY_STRING': '', 'REMOTE_ADDR': '127.0.0.1', 'CONTENT_TYPE': 'text/plain', 'HTTP_HOST': '127.0.0.1:8000', 'HTTP_CONNECTION': 'keep-alive', 'HTTP_CACHE_CONTROL': 'max-age=0', 'HTTP_UPGRADE_INSECURE_REQUESTS': '1', 'HTTP_USER_AGENT': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.119 Safari/537.36', 'HTTP_ACCEPT': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8', 'HTTP_ACCEPT_ENCODING': 'gzip, deflate, br', 'HTTP_ACCEPT_LANGUAGE': 'zh-CN,zh;q=0.9', 'wsgi.input': <_io.BufferedReader name=464>, 'wsgi.errors': <_io.TextIOWrapper name='<stderr>' mode='w' encoding='UTF-8'>, 'wsgi.version': (1, 0), 'wsgi.run_once': False, 'wsgi.url_scheme': 'http', 'wsgi.multithread': True, 'wsgi.multiprocess': False, 'wsgi.file_wrapper': <class 'wsgiref.util.FileWrapper'>}

 簡單的上傳服務

def upload(request):
    """
    保存上傳文件前,數據須要存放在某個位置。默認當上傳文件小於2.5M時,django會將上傳文件的所有內容讀進內存。從內存讀取一次,寫磁盤一次。
    但當上傳文件很大時,django會把上傳文件寫到臨時文件中,而後存放到系統臨時文件夾中。
    :param request: 
    :return: 
    """
    if request.method == "POST":
        # 從請求的FILES中獲取上傳文件的文件名,file爲頁面上type=files類型input的name屬性值
        filename = request.FILES["file"].name
        # 在項目目錄下新建一個文件
        with open(filename, "wb") as f:
            # 從上傳的文件對象中一點一點讀
            for chunk in request.FILES["file"].chunks():
                # 寫入本地文件
                f.write(chunk)
        return HttpResponse("上傳OK")

request方法

request.get_full_path()         獲取全路徑 即路徑和參數

print(request.get_full_path())

/app1/update/?zj=16    

request.is_secure()                 若是請求時是https,則返回True;反之False

response對象

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

from django.http import JsonResponse     #引用JsonResponse
def json_text(request):
    data = {'name':'wk','age':18}
    return JsonResponse(data)            #這樣前端就能接收到json格式的數據 

默認只能傳遞字典類型,若是要傳遞非字典類型須要設置一下safe關鍵字參數。
JsonResponse([1, 2, 3], safe=False)

Django模板系統

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

{{  }}和 {% %}

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

變量

{{ 變量名 }}

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

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

def test(request):
    l = [1, 2, 3]
    d = {'name':'wk'}

    class dd_a():
        def __init__(self, name, age):
            self.name = name
            self.age = age
        def dream(self):
            return "%s 1111" %(self.name)

    Wk = dd_a('wk',15)
    wc = dd_a('wc',13)
    ww = dd_a('ww',18)
    pp = [Wk,wc,ww]
    return render(request, "test.html",{'l':l,'d':d, 'pp':pp} )

 在html 取變量

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
{{ l.0 }}            #根據索引取列表的值 <br> 
{{ l.1 }}             #取列表的第一個值 <br>
{{ d.name }}        #根據key取字典的值 <br> 
{{ d.keys }}           #取字典的全部key values 取字典全部的值 items取字典的鍵值 <br>
{{ pp.0.name }}        #取列表pp第一個對象的 name屬性 <br>
{{ pp.0.age }}           
<br>
{{ pp.0.dream }}        #使用pp列表第一個對象的dream方法 </body>
</html>

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

  1. 在字典中查詢
  2. 屬性或者方法
  3. 數字索引

Filters   過濾器

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

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

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

default  

{{ value|default:"nothing"}}

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

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

filesizeformat

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

{{ value|filesizeformat }}

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

add

給變量加參數

{{ value|add:"2" }}

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

{{ first|add:second }}

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

lower

小寫

{{ value|lower }}

upper

大寫

{{ value|upper}}

title

標題

{{ value|title }}

ljust

左對齊

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

rjust

右對齊

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

center

居中

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

length

{{ value|length }}

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

slice  

切片

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

first

取第一個元素

{{ value|first }}

last

取最後一個元素

{{ value|last }}

join

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

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

truncatechars

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

參數:截斷的字符數

{{ value|truncatechars:9}}

date

views視圖添加時間

import datetime

def test(request):
    Date = datetime.datetime.now()
    return render(request, "test.html",{'date':Date})

日期格式化

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

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

日期也能夠改配置文件顯示

修改settings.py文件

USE_L10N = False 
DATETIME_FORMAT = 'Y-m-d H:i:s'

 此時html只須要寫   {{ date }}

就顯示格式化的日期

safe (轉譯,把傳進來的字符串轉譯爲html可識別的語言)

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

好比:

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

{{ value|safe}}

Tags

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 當前循環是否是第一次循環(布爾值)若是是第一次顯示True  後邊的每次循環顯示Flase
forloop.last 當前循環是否是最後一次循環(布爾值)
forloop.parentloop 本層循環的外層循環

 

def test(request):
    class dd_a():
        def __init__(self, name, age):
            self.name = name
            self.age = age
        def dream(self):
            return "%s 1111" %(self.name)
    Wk = dd_a('wk',15)
    wc = dd_a('wc',13)
    ww = dd_a('ww',18)
    pp = [Wk,wc,ww]
    return render(request, "test.html",{'pp':pp} )


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <ul>
        {% for ps in pp %}
            <li>{{ forloop.counter }} = {{ ps.name }}</li>
        {% endfor %} 
    </ul>
</body>
</html>

for ... empty   當循環爲空時走empty

  {% for foo in all %}
                        <tr>
                            <td>{{ forloop.counter }}</td>
                            <td>{{ foo.pk }}</td>
                            <td>{{ foo.mane }}</td>
                            <td>
                                <a href="{% url 'app1:del' %}?sh={{ foo.pk }}" class="btn btn-danger btn-sm">刪除</a>
                                <a href="{% url 'app1:update' %}?zj={{ foo.pk }}" class="btn btn-primary btn-sm">編輯</a>
                            </td>
                            <td>
                                {% empty %}             {# 當for循環爲空時,顯示empty的內容 #}
                                <td>空的</td>
                            </td>
                        </tr>
                    {% endfor %}

if,elif和else

  {% for foo in all %}
                        <tr {% if forloop.first %} style="color: red" {% endif %}>       #若是是第一次循環得出的結果則顯示紅色
                            <td>{{ forloop.counter }}</td>
                            <td>{{ foo.pk }}</td>
                            <td>{{ foo.mane }}</td>
                            <td>
                                <a href="{% url 'app1:del' %}?sh={{ foo.pk }}" class="btn btn-danger btn-sm">刪除</a> 
                                <a href="{% url 'app1:update' %}?zj={{ foo.pk }}" class="btn btn-primary btn-sm">編輯</a>
                            </td>
                            <td>
                                {% empty %}
                                <td>空的</td>
                            </td>
                        </tr>
                    {% endfor %}
複製代碼
{% 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判斷。

 with 給變量起別名

{% with oldname as newname %}
    {{ newname }}
{% endwith %}

csrf_token

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

在頁面的form表單裏面寫上{% csrf_token %} ,這樣不用註釋中間件 也能夠提交post請求

   <form class="form-horizontal" action="" method="post">  
                    {% csrf_token %}           {# 加在form表單下 #}

母板

 母版就是一個普通的頁面,存放全部頁面公共的代碼,定義好block塊,讓子頁面進行重寫

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="/static/css/bootstrap.min.css">
    <link rel="stylesheet" href="/static/css/das.css">
</head>
<body>

<nav class="navbar navbar-inverse navbar-fixed-top">
    <div class="container-fluid">
        <div class="navbar-header">
            <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar"
                    aria-expanded="false" aria-controls="navbar">
                <span class="sr-only">Toggle navigation</span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
            </button>
            <a class="navbar-brand" href="#">出版社管理</a>
        </div>
        <div id="navbar" class="navbar-collapse collapse">
            <ul class="nav navbar-nav navbar-right">
                <li><a href="#">Dashboard</a></li>
                <li><a href="#">Settings</a></li>
                <li><a href="#">Profile</a></li>
                <li><a href="#">Help</a></li>
            </ul>
            <form class="navbar-form navbar-right">
                <input type="text" class="form-control" placeholder="Search...">
            </form>
        </div>
    </div>
</nav>

<div class="container-fluid">
    <div class="row">
        <div class="col-sm-3 col-md-2 sidebar">
            <ul class="nav nav-sidebar">
                <li class="active"><a href="{% url 'app1:zhanshi' %}">出版社列表 <span class="sr-only">(current)</span></a></li>
            </ul>
        </div>
        <div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main">
            {% block main %}
            {% endblock %}                 {# 母版只保留公共部分,而且定義block來定位不一樣的部分#}
        </div>
    </div>
</div>

繼承{% extends 'layouts.html' %}    子頁面繼承母版,而且在block塊里加上不一樣的東西

{% extends 'muban.html' %} {# 繼承母版 #}

{% block main %}           {# 在blick 定位的地方加上不通的部分#}
            <h2 class="sub-header">出版社信息</h2>
            <div class="table-responsive">
            <a href="{% url 'app1:add2' %}" class="btn btn-primary">添加</a>
                <table class="table table-striped table-hover">
                    <thead>
                    <tr>
                        <th>序號<th>
                        <th>ID</th>
                        <th>出版社名稱</th>
                        <th>操做</th>
                    </tr>
                    </thead>
                    <tbody>
                    {% for foo in all %}
                        <tr {% if forloop.first %} style="color: red" {% endif %}>
                            <td>{{ forloop.counter }}</td>
                            <td>{{ foo.pk }}</td>
                            <td>{{ foo.mane }}</td>
                            <td>
                                <a href="{% url 'app1:del' %}?sh={{ foo.pk }}" class="btn btn-danger btn-sm">刪除</a>
                                <a href="{% url 'app1:update' %}?zj={{ foo.pk }}" class="btn btn-primary btn-sm">編輯</a>
                            </td>
                            <td>
                                {% empty %}
                                <td>空的</td>
                            </td>
                        </tr>
                    {% endfor %}
                    </tbody>
                </table>
            </div>
{% endblock %}

注意點:

  1.  {% extends 'muban.html' %} 寫在第一行

  2.   不一樣的內容寫在這中間{% block main %}

   3.子頁面和主頁面不一樣的靜態css js也能夠經過block 添加

組件

一小段公用的html代碼 不少頁面要用的  把這段代碼保存到html文件裏

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

{% include 'toubuxinxi.html' %}

 公共頭部文件代碼 toubuxinxi.html

<nav class="navbar navbar-inverse navbar-fixed-top">
    <div class="container-fluid">
        <div class="navbar-header">
            <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar"
                    aria-expanded="false" aria-controls="navbar">
                <span class="sr-only">Toggle navigation</span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
            </button>
            <a class="navbar-brand" href="#">出版社管理</a>
        </div>
        <div id="navbar" class="navbar-collapse collapse">
            <ul class="nav navbar-nav navbar-right">
                <li><a href="#">Dashboard</a></li>
                <li><a href="#">Settings</a></li>
                <li><a href="#">Profile</a></li>
                <li><a href="#">Help</a></li>
            </ul>
            <form class="navbar-form navbar-right">
                <input type="text" class="form-control" placeholder="Search...">
            </form>
        </div>
    </div>
</nav>

在修改頁面添加頭部

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="/static/css/bootstrap.min.css">
    <link rel="stylesheet" href="/static/css/das.css">
</head>
<body>
    {% include 'toubuxinxi.html' %}
    <br>
<form class="form-horizontal" action="" method="post">
    {% csrf_token %}
    <div class="form-group">
        <label for="inputEmail3" class="col-sm-2 control-label">出版社名稱</label>
        <div class="col-sm-10">
            <input type="text" class="form-control" id="inputEmail3" placeholder="出版社名稱" name="newname"
                   value="{{ obj.mane }}">
        </div>
    </div>
    <div class="form-group">
        <div class="col-sm-offset-2 col-sm-10">
            <button type="submit" class="btn btn-default">修改</button>
        </div>

</body>
</html>

靜態文件相關

{% load static %}

head裏得引用靜態文件的static是寫死了

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="/static/css/bootstrap.min.css">
    <link rel="stylesheet" href="/static/css/das.css">
</head>

若是settings.py文件裏的static修改了則每一個引用都要改

STATIC_URL = '/static/'
STATICFILES_DIRS = [
    os.path.join(BASE_DIR,'static')

所以使用{% load static %}來解決

<head>
    <meta charset="UTF-8">
    <title>Title</title>
    {% load static %}             
{#    <link rel="stylesheet" href="/static/css/bootstrap.min.css">#}
      <link rel="stylesheet" href={% static "css/bootstrap.min.css"%}>   {#變量名拼接相對路徑#}
{#    <link rel="stylesheet" href="/static/css/das.css">#}
     <link rel="stylesheet" href={% static "css/das.css"%}>
</head>

此時改變STATIC_URL = 的值頁面也照常訪問

STATIC_URL = '/11111/'
STATICFILES_DIRS = [
    os.path.join(BASE_DIR,'static')

{% load static %}的使用

{% 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   取的是settings.py裏STATIC_URL 的值

這種用法至關於使用絕對路徑

{% 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!" />

 外鍵的操做

 在數據庫增長關聯表

from django.db import models

# Create your models here.
class tusu(models.Model):
    pid = models.AutoField(primary_key=True)
    mane = models.CharField(max_length=32)
class Book(models.Model):                 #新增表Book title = models.CharField(max_length=32) #定義書名 tusu = models.ForeignKey('tusu',on_delete=models.CASCADE) #定義外鍵鏈接 鏈接的的表是tusu, on_delete=models.CASCADE 即若是出版社刪除了對應的書也刪除

變動數據庫

 python3 manage.py makemigrations
 python3 manage.py migrate

新建的book表

加入數據後

  

作展現頁

url略

views.py

def newzs(request):
    books = models.Book.objects.all()       #查出book表的信息 return render(request,'newzs.html',{'books':books})  #傳到前端

前端 用母版  拿外鍵的值直接點外鍵名(不要加_id)獲得外鍵表的對象再點對應的key拿值

{% extends 'muban.html' %}
{% block main %}
            <h2 class="sub-header">書籍信息</h2>
            <div class="table-responsive">
{#            <a href="{% url 'app1:add2' %}" class="btn btn-primary">添加</a>#}
                <table class="table table-striped table-hover">
                    <thead>
                    <tr>
                        <th>序號<th>
                        <th>ID</th>
                        <th>出版社名稱</th>
                        <th>書名 </th>
                        <th>操做</th>
                    </tr>
                    </thead>
                    <tbody>
                    {% for book in books %}
                        <tr {% if forloop.first %} style="color: red" {% endif %}>
                            <td>{{ forloop.counter }}</td>
                            <td>{{ book.pk }}</td>
                            <td>{{ book.tusu.mane }}</td> {# book.tusu點出來的不是外鍵的值而是對應的tusu表的對象,經過對象.key拿對應的值 #}
                            <td>{{ book.title }}</td>
                            <td>
                                <a href="{% url 'app1:del' %}?sh={{ foo.pk }}" class="btn btn-danger btn-sm">刪除</a>
                                <a href="{% url 'app1:update' %}?zj={{ foo.pk }}" class="btn btn-primary btn-sm">編輯</a>
                            </td>
                            <td>
                                {% empty %}
                                <td>空的</td>
                            </td>
                        </tr>
                    {% endfor %}
                    </tbody>
                </table>
            </div>
{% endblock %}

刪除出版社 ,對應的書也沒了

 添加功能

url略

views.py

class newadd(View):
    def get(self,request): 
        tusu = models.tusu.objects.all()  #獲取全部出版社的信息返回給前端 return render(request,'newadd.html',{'tusu':tusu})
    def post(self,request):                #post請求添加出版舍
        newname = request.POST.get('newname')      #獲取要添加的書的名字
        put = request.POST.get('put')              #獲取要添加的書名對應的外鍵的值
        models.Book.objects.create(title=newname,tusu_id=put)     #建立新數據 return redirect(reverse('app1:newzs'))

前端展現頁功能 直接跳轉

   <a href="{% url 'app1:newadd' %}" class="btn btn-primary">添加</a>

添加頁功能

 <div class="table-responsive">
                <form class="form-horizontal" action="" method="post">
                    <div class="form-group">
                        <label for="inputEmail3" class="col-sm-2 control-label">書名</label>
                        <div class="col-sm-10">
                            <input type="text" class="form-control" id="inputEmail3" placeholder="書名" name="newname">
                        </div>
                    </div>
                    <div class="form-group">
                        <label for="inputEmail3" class="col-sm-2 control-label">出版社</label>
                        <div class="col-sm-10">
                            <select name="put" id="inputEmail3" class="form-control">
                                {% for i in tusu %}
                                    <option value="{{ i.pk }}">{{ i.mane }}</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>

 修改功能

url

    url(r'upda/(\d+)$', aap1vw.upda.as_view(),name='upda'),   #使用分組的方法

views.py

class upda(View):
    def get(self,request,zh):           #分組要在這裏接收前端傳來的分組的位置參數 Book表的主鍵
         # zh = request.GET.get('zh')        #這是以前的接受前端傳來的?號的方法 如今用分組的方法
        book_obg = models.Book.objects.get(pk=zh)
        tusu = models.tusu.objects.all()
        return render(request,'upda.html',{'book_obg':book_obg,'tusu':tusu})
    def post(self,request,zh):
        book_obg = models.Book.objects.get(pk=zh)  #拿到原有的書的對象
        upname = request.POST.get('upname')   #拿到修改後的書名
        put = request.POST.get('put')         #拿到修改後的書的對應的外鍵的值
        book_obg.title = upname
        book_obg.tusu_id = put
        book_obg.save()
        return redirect(reverse('app1:newzs'))

展現頁提交信息          #分組url獲得的參數是Book表的主鍵

<a href="{% url 'app1:upda' book.pk %}" class="btn btn-primary btn-sm">編輯</a>  

修改頁功能

<div class="col-sm-10">
<input type="text" class="form-control" id="inputEmail3" placeholder="書名" name="upname" value="{{ book_obg.title }}"> 
</div>
<div class="form-group">
<label for="inputEmail3" class="col-sm-2 control-label">出版社</label>
<div class="col-sm-10">
<select name="put" id="inputEmail3" class="form-control">
     {% for i in tusu %}
     {% if book_obg.tusu == i %}   {# book_obg是前端提交的對象,加點外鍵對應的鍵即獲得對應連接的對象 而後對比前端發來的對象是否是當次循環的對象 #}
      <option selected value="{{ i.pk }}">{{ i.mane }}</option>   {# 若是循環列表該次循環的對象是前端get提交來的對象 是就 selected 選中 #}
      {% else %}
      <option value="{{ i.pk }}">{{ i.mane }}</option>   {# 若是不是就不選中 #}
      {% endif %}
      {% endfor %}
 </select>
</div>
</div>

刪除功能將出版社和圖書的刪除合併

url    定義兩個分組分別傳數據庫對面的名字和對應的主鍵

url(r'del_(tusu|book)/(\d+)/$', aap1vw.Del,name='Del'),

前端傳出的值

    1.出版社傳出的值爲 對應的數據庫名 和對應 的主鍵值 

<a href="{% url 'app1:Del' 'tusu' foo.pk %}" class="btn btn-danger btn-sm">刪除</a>

    2. 圖書傳出的值爲 對應的數據庫名 和對應的 主鍵值

<a href="{% url 'app1:Del' 'book' book.pk %}" class="btn btn-danger btn-sm">刪除</a>

views.py 文件邏輯

def Del(request,zz,hh):       #分別接收前端傳來的兩個參數
    if zz == 'tusu':          #圖書的返回圖書的展現頁,出版社的返回出版社的  
        dd = 'app1:zhanshi' 
    elif zz == 'Book':        #此處能夠優化 把展現頁的別名改成對應數據庫對象的名字
        dd = 'app1:newzs'     #能夠省略以上4行代碼
    Obj = getattr(models,zz)    #反射獲得models 裏的對應的圖書的或出版社的數據庫對象
    Obj.objects.get(pk=hh).delete()    #刪除對應的數據庫對象的選中的主鍵
    return redirect(reverse(dd))  #返回對應的展現頁
相關文章
相關標籤/搜索