django學習與實踐

Django簡介

​ Django是一個由Python寫成的開放源代碼的Web應用框架,它最初是被用來開發管理勞倫斯出版集團旗下的一些以新聞內容爲主的網站,即CMS(內容管理系統)軟件。 並於2005年7月在 BSD 許可證下發布。這套框架是以比利時的吉普賽爵士吉他手 Django Reinhardt 來命名的。因爲 Django 的是在一個快節奏的新聞編輯室環境下開發的,它的目的是使常見的 Web 開發任務,快速和容易。css

Django官網:https://www.djangoproject.com/html

Django中文網:https://www.django.cnpython

Django的框架模式mysql

  • Django採用了MTV設計模式git

    M Models 模型
    T Templates 模板
    V Views 視圖

img

Django是一個Web應用框架,他是如何處理請求和響應的正則表達式

DJANGO MVC - MVT模式

URL ( urls.py )請求調度,當有緩存頁面的時候直接返回內容。
視圖函數( view.py )執行所請求的操做,一般包括讀寫數據庫。
模型( models.py )定義了 Python 中的數據並與之交互。一般包含在一個關係數據庫( MySQL、PostgreSQL SQLite 等),其餘數據存儲是可能的( XML、文本文件、LDAP、等)。
請求執行任務後,視圖返回一個 HTTP 響應對象(一般是通過數據處理的一個模板)。可選的:視圖能夠保存一個版本的 HTTP 響應對象,返回攜帶一個時間戳,來告訴瀏覽器這個視圖的更新時間。
模板一般返回 HTML 頁面。Django 模板語言提供了 HTML 的語法及邏輯。算法

安裝

第一行和第三行均可以隨便使用sql

網絡很差用第三行數據庫

pip install Django==2.1
#用國內的鏡像網站,以下
pip install Django==2.1 -i https://pypi.douban.com/simple

導入Django模塊

import django
print(django.get_version())
#結果:
2.1

基本配置

經常使用命令

查看django版本
python -m django --version
#結果
2.1
建立項目命令,項目名稱是mysite
django-admin startproject mysite
建立應用程序命令,確保在manage.py文件時在同一個目錄
#若是咱們在項目外面,先要進入項目裏
cd mysite
#windows使用dir查看當前在哪裏,若是有manage.py就表明咱們能夠正確使用下面的命令
#建立應用程序
python manage.py startapp app01

啓動django

python manage.py runserver
#默認端口是8000
#使用上面的命令就能夠了,下面不常常用
#改端口
python manage.py runserver 8080
#改訪問地址和端口
python manage.py runserver 0.0.0.0:8080

生成模型變化遷移文件

python manage.py makemigrations

運行模型遷移文件遷移到數據庫中

python manage.py migrate

建立管理用戶

python manage.py createsuperuser
user:輸入:admin
email:不寫也行
password:輸入:admin123
驗證password:輸入:admin123
 讓你確認:輸入:y

注:自動從新加載 runserver,根據須要開發服務器自動從新加載Python代碼爲每一個請求。您不須要從新啓動服務器代碼更改生效。然而,像添加文件某些操做不觸發從新啓動,因此你必須從新啓動在這些狀況下的服務器。django

基本目錄結構及做用:
mysite/ # 項目的容器,名字隨便起
manage.py # 命令行實用工具,以各類方式與該Django項目進行交互
mysite/ # 實際的Python項目
init.py # 空文件,導入不出錯
settings.py # 這個Django項目配置
urls.py # 這個Django項目的URL聲明; 一個Django驅動網站的「目錄」
wsgi.py # 一個入口點爲WSGI兼容的Web服務器,以知足您的項目

Django自帶數據庫,咱們也能夠選擇不更改,項目開發中通常會更改使用的數據庫,更改數據庫配置在settings.py文件裏

因爲Django內部鏈接MySQL時使用的是MySQLdb模塊

目前可使用mysql來代替pymysql了

咱們須要去下載mysql
pip install mysql

在settings中修改DATABASES

DATABASES = {
    'default'{
        'ENGINE':'django.db.backends.mysql',
        'NAME':'你的數據庫名稱',
        'USER':'你的用戶名',
        'PASSWORD':'你的密碼',
        'HOST':'127.0.0.1',
        'PORT':'3306',
    }           
}

模板

也在settings裏修改,主要放html文件

TEMPLATE_DIRS = (
os.path.join(BASE_DIR,'templates'),
)

靜態文件

也在settings裏修改,放css,js等文件

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

路由系統

路由系統就像咱們咱們的書本的目錄,書本的目錄會告訴你那一頁是什麼,你翻到那一頁就能看到相關的文字,路由系統就是,你對這個路由系統裏的一個url地址發起了請求,路由系統會到對應的views函數去進行相關的處理,即這個url要用某個指定的views函數去處理。

來看下示例,django是怎麼規定構造路由的

from app01 import views
urlpatterns = [
    path(r'^login$',views.LoginView),
    path(r'^register$',views.RegisterView),
]
from app1 import views
urlpatterns = [
url(r'^manage1/(\d)', views.manage1),
url(r'^manage2/(?P\w)/(?P\d)', views.manage2),
url(r'^manage3/(?P\w)', views.manage3,{'id':333}),]

注意:

url多傳一個參數,那views對應的函數就要多接收一個參數

要否則會報錯的

二級路由

若是映射url太多了,全寫在一個urls.py文件裏顯得繁瑣,因此出現了二級路由

就是項目的urls.py文件負責接收客戶發過來請求它判斷你傳來的東西有沒有它下面應用裏的urls.py文件裏有沒有,若是有就告訴應用的的urls來接收,讓它去處理,沒有就給你報錯

一級路由寫法

項目的urls.py文件裏

from django.urls import path, include
urlpatterns = [
    path(r'app01/',include('app1.urls'))
]

Django是如何處理一個請求的

當用戶請求從您的 Django 的網站頁面,這是該系統遵循以肯定哪些 Python 代碼執行的算法:

Django 請求是 URL 配置模塊配置。一般經過值 ROOT_URLCONF 設置,但若是傳入 HttpRequest 對象具備 urlconf 屬性(由中間件設置),它的值將代替的可使用 ROOT_URLCONF 的設置。
Django 的負載是 Python 模塊並尋找變量 urlpatterns。這是一個 django.conf.urls.url() 實例。
Django 的貫穿每一個 URL 模式,從而,在所請求的 URL 匹配的第一個中止。
一旦某個正則表達式相匹配,就運行相對應的視圖函數(或基於類的視圖)。該視圖被傳遞如下參數:
HttpRequest 對象。
若是匹配的正則表達式沒有返回命名組,而後從正則表達式比賽是做爲位置參數。
關鍵詞參數是由由正則表達式匹配的任何命名組,由指定的可選參數的任何覆蓋的 kwargs參數 django.conf.urls.url()。
若是沒有正則表達式匹配,或者若是一個異常在這個過程當中的任何一點時提出,Django的調用適當的錯誤處理視圖。

官方示例

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

注意事項:

要捕獲從URL中的值,用 括號括起來,會當參數傳入views視圖

沒有必要添加一個斜體,由於每一個URL都有。例如,它^articles不是^/articles.

在‘r’前面的每個正則表達式是可選的,建議,它告訴python字符串是原始的,沒有字符要轉義

舉例請求:

請求/articles/2005/03/將匹配列表中的第三項,Django將調用該函數。

views.month_archive(request,‘2005’,‘03’)

/articles/2005/3/ 不會匹配任何 URL 模式,由於在列表中的第三項中須要兩位數字的月份。

/articles/2003/ 將匹配的列表,而不是第二個第一圖案,由於該圖案,以便測試,第一個是在第一測

試經過。隨意利用順序插入特殊狀況是這樣的。在這裏,Django的將調用該函數

views.special_case_2003(request)

/articles/2003 不匹配任何這些模式,由於每一個模式要求 URL 以斜線結束。

/articles/2003/03/03/ 將匹配的最終格局。Django 的將調用該函數。

views.article_detail(request,'2003', '03', '03')

命名組

上面的例子使用了簡單的,非命名的正則表達式組(經過括號)來捕獲URL的位,並經過他們的位置參數的視圖,在更高級的用法,它可使用命名正則表達式組成來捕獲URL位,將它們做爲關鍵字參數傳遞給視圖。

例子:

from django.conf.urls import url
from .import views
urlpatterns = [
    url(r'^articles/2003/$',views.special_case_2003),
    url(r'^articles/(?P[0-9]{4})/$',views.year_archive),
    url(r'^articles/(?P[0-9]{4})/(?P[0-9]{2})/$', views.month_archive),
    url(r'^articles/(?P[0-9]{4})/(?P[0-9]{2})/(?P[0-9]{2})/$',views.article_detail),
]

這正好完成一樣的事情,前面的例子,一個細微的差異:捕獲的值傳遞給查看功能做爲關鍵字參數,而不是位置參數。例如:

請求/articles/2005/03/會調用函數來代替,views.month_archive(request, year='2005',month='03')views.month_archive(request, '2005', '03')
請求/articles/2003/03/03/會調用該函數,views.article_detail(request, year='2003',month='03', day='03')
在實踐中,這意味着你的 URLconf 稍微更明確,不容易參數順序錯誤 - 你能夠在你的意見'函數定義從新排序的參數。固然,這些優勢來在簡短的費用; 一些開發任務命名組的語法醜陋,太冗長。

匹配/分組算法
這裏的URL配置解析器遵循算法,相對於正則表達式命名組與非命名組:

若是有任何命名參數,它會使用這些,而忽略非命名參數。
不然,它會經過全部非命名參數做爲位置參數。
在這兩種狀況下,被賦予按任何額外的關鍵字參數傳遞額外的選項來查看功能也將被傳遞給視圖請求/articles/2005/03/會調用函數來代替,views.month_archive(request,year=‘2005’,month=‘03’)

3> What the URLconf searches against
The URLconf searches against the requested URL, as a normal Python string. This does not include GET or POST parameters, or the domain name.

For example, in a request to https://www.example.com/myapp/, the URLconf will look for myapp/.

In a request to https://www.example.com/myapp/?page=3, the URLconf will look for myapp/.

該URL配置不看請求方法。換言之,全部的請求的方法,GET,POST 等將被路由到爲相同的URL,相同的功能。

4> 捕獲的參數老是字符串
每一個捕獲的參數發送到視圖做爲普通的 Python 字符串,不管什麼樣的匹配正則表達式匹配。

例如,在該URL配置行:

url(r'^articles/(?P[0-9]{4})/$', views.year_archive),
...的 year參數傳遞給 views.year_archive()將是一個字符串,

不是一個整數,即便 [0-9]{4} 將只匹配整數字符串。

5> 指定view的默認設置
一個方便的技巧是你的觀點的論據指定默認參數。下面是一個例子的 RLconf 和見解:

urlconf

from django.conf.urls import url
from . import views
urlpatterns = [
    url(r'^blogs/$',views.page),
    url(r'blog/page(?P[0-9]+)/$',views.page),
]

views.py

def page(request,num='1'):
    '''
    處理語句塊
    '''

視圖層

對邏輯負責處理用戶的請求並返回相應,返回能夠是HTML內容的網頁,或者重定向,或者錯誤,或者字典

每一個應用都有views.py文件

返回快捷鍵功能

render()
render(request,template_name,context=None,content_type=None,status=None,using=None)[source]

結合給定的模板與一個給定的上下文,返回一個字典HttpRespone在渲染文本對象

所需的參數

template_name 一個模板的使用或模板序列名稱全稱。若是序列是給定的,存在於第一個模板將被使用。

可選參數

context 一組字典的值添加到模板中,默認狀況下這是一個孔子點

content_type MIME類型用於生成文檔

status 爲響應狀態代碼,默認值爲200

using這個名字一個模板引擎將使用的模板

例子:

from django.shortcuts import render
def my_view(request):
    return render(request,'myapp/index.html',{'fpp','bar',},content_type='application/xhyml+xml')

重定向

redirect()

redirect(to,permanent=False,*args,**kwargs)[source]
默認狀況下,爲臨時重定向,經過permanent=True設置永久重定向

例子:

def my_view(request):
    ...
    return redirect('/some/url/')
def my_view(request):
    ...
obj = MyModel.opbjects.get(...)
return redirect(object,permanent=True)

請求和響應對象

django使用請求和響應對象在系統間傳遞狀態

當請求一個頁面時,django建立一個HttpRequest對象包含原數據的請求,而後django加載適當的視圖,經過HttpRequest做爲視圖函數的第一個參數,每一個視圖負責返回一個HttpResponse目標

HttpRequest對象

HttpRequest.scheme

一個字符串表示請求的計劃方案(HTTP或者HTTPS)

一般HttpRequest.path

一個字符串的完整路徑的請求

HTTPRequest.method

請求HTTP的方法,這裏保證要大寫

#僞代碼
if request.method == 'GET':
    '''
    執行業務代碼
    返回結果
    '''
    return HttpResponse('結果')
#業務邏輯:若是請求來的是GET,你返回個GET字符串
#真代碼
class GETView(objects):
    def getview(self,request):
        if request.method == 'GET':
            return HttpResponse('GET')
if request.method == 'GET':
    return HttpResponse('GET')
elif request.method == 'POST':
    return HttpResponse('POST')
elif request.method == 'PUT':
    return HttpResponse('PUT')
elif request.method == 'DELETE':
    return HttpResponse('DELETE')
else:
    return HttpResponse('來了老弟!')

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

HttpRequest.GET

字典包含全部給定的HTTP POST 參數對象,提供請求包含表單數據

HttpRequest.POST

一個標準的python字典,包含全部的COOKIES,KEY和VALUES都是字符串

字典包含全部上傳的文件

HttpRequest.FILES

語法:

HttpRequest.FILES
filename #上傳的文件名
content_type #上傳文件的類型
content #上傳文件的內容

HttpRequest.META

一個標準的Python字典包含全部可用的HTTP頭,可用標題取決於客戶端和服務器。如下是例子

CONTENT_LENGTH 請求體的長度(一個字符串
CONTENT_TYPE 請求體的類型
HTTP_ACCEPT 爲響應–能夠接受的內容類型
HTTP_ACCEPT_ENCODING 接受編碼的響應
HTTP_ACCEPT_LANGUAGE 接受語言的反應
HTTP_HOST 客戶端發送的HTTP主機頭
HTTP_REFERER 參考頁面
HTTP_USER_AGENT 客戶端的用戶代理字符串
QUERY_STRING 查詢字符串,做爲一個單一的(分析的)字符串
REMOTE_ADDR 客戶端的IP地址
REMOTE_HOST 客戶端的主機名
REMOTE_USER 用戶經過Web服務器的身份驗證
REQUEST_METHOD 字符串,如"GET"或"POST"
SERVER_NAME 服務器的主機名
SERVER_PORT 服務器的端口(一個字符串)

HttpResponse對象

對於HttpRequest 對象來講,是由django自動建立的,可是,HttpResponse 對象就必須咱們本身建立。每一個 view 請求處理方法必須返回一個 HttpResponse 對象。

HttpResponse 類在 django.http.HttpResponse

字符串使用:
典型的用法是經過頁面的內容,爲一個字符串

for django.http import HttpResponse
response = HttpResponse("hello world")
response = HttpResponse("hello world",content_type="text/plain")

若是你想添加內容的增量

response = HttpResponse()
response.write("hello world")
response.write("你好")
#特性與方法:
HttpResponse.content
一個bytestring表明內容HttpResponse.charset

一個字符串的字符集表示的響應將編碼

HttpResponse.status_code

HTTP狀態代碼爲響應碼

HttpResponse.streaming

這個屬性永遠爲假,通常用於中間件

HttpResponse.closed

方法:

先寫的代碼,後寫的註釋

HttpResponse.__init__(content='',content_type=None,status=200,reason=None,charset=None)[source]
#實例化類自動執行的方法
HttpResponse.__setitem__(header,value)
#爲給定值給定的標題名稱,都是字符串
HttpResponse.__delitem__(header)
#刪除標題的名稱,不區分大小寫
HttpResponse.__getitem__(header)
#獲取給定標題名稱。不區分大小寫。
HttpResponse.has_header(header)

#檢查是否具備給定名稱的一個標題
HttpResponse.setdefault(header, value)

#設置一個標題,除非它已經設置。
HttpResponse.set_cookie(key, value='', max_age=None, expires=None, path='/', domain=None, secure=None, httponly=False)

#設置一個cookie。參數跟標準庫的Cookie對象差很少
HttpResponse.set_signed_cookie(key, value, salt='', max_age=None, expires=None, path='/', domain=None, secure=None, httponly=True)

#加密cookice,能夠用 HttpRequest.get_signed_cookie() 獲取,固然你也能夠加鹽
HttpResponse.delete_cookie(key, path='/', domain=None)

#刪除Cookie與給定鍵。

#HttpResponse子類:
class HttpResponseRedirect[source]

構造函數的第一個參數是必需的路徑redirectto,這是一個徹底合格的URL,一個合格的URL(https://www.baidu.com/搜索/),沒有一個絕對的路徑(例如:域搜索//),甚至是相對路徑(如‘/’),

optionalconstructor參數。請注意,這將返回一個HTTP狀態代碼302。
class HttpResponsePermanentRedirect[source]

像httpresponseredirect,但它返回一個永久重定向(HTTP狀態代碼301)而不是「發現」的重定向(狀態代碼302)
class HttpResponseNotModified[source]

構造函數不帶任何參數和NO含量應該被添加到這一反應。使用指定一個頁面沒有被modifiedsince用戶的最後一個請求(狀態代碼304)。
class HttpResponseBadRequest[source]

就像HttpResponse但使用400狀態碼
class HttpResponseNotFound[source]

就像HttpResponse但使用404狀態碼
class HttpResponseForbidden[source]

就像HttpResponse但使用403狀態碼
class HttpResponseNotAllowed[source]

像HttpResponse,但使用405狀態碼。第一argumentto構造函數要求准許清單的方法(如(get,後])
class HttpResponseGone[source]

就像HttpResponse但使用410狀態碼
class HttpResponseServerError[source]

就像HttpResponse但使用500狀態碼

模板層

做爲一個Web框架,Django須要模板,模板包含所需的HTML輸出靜態部分以及動態內容插入。
模板的執行
from datetime import datetime
def current_datetime(request):
    now = datetime.datetime.now()
    html = "it is now %s" % now
    return HttpResponse(html)

from django import template
t = template.Templatge("my name is {{name}}")
c = template.Context({"name":"老王"})
print(t.render(c))


import datetime
from django import template
import DjangoDemo.settings
now = datetime.datetime.now()
fp = open(settings.BASE_DIR+"/templates/home/index.html")
t = template.Template(fp.read())
fp.close()
html = t.render(template.Context({'current_date':now}))
return HttpResponse(html)

from django.template.loader import get_template
from django.template import Context
from django.http import HttpResponse
import datetime
def current_datetime(request):
    now = datetime.datetime.now()
    t = get_template('current_datetime.html')
    html = t.render(Content({'current_date':now}))
    return HttpResponse(html)
reurn render_to_response("Account/login.html",data,context_instance=RequestContext(request))

模板語言

模板中也有本身的語言,該語言實現數據展現
{{item}}
{% for item in item_list %}
    {{item}}
{% endfor %}
forloop.counter
forloop.first
forloop.last
{% if ordered_warranty %}
    {% else %}
{% endif %}
母板:{% block title %}{% endblock %}
子板: {% extends"base.html" %}
幫助方法:
{{ item.event_start|date:"Y-m-d H:i:s"}}
{{ bio|truncatewords:"30" }}
{{ my_list|first|upper }}
{{ name|lower }}

自定義simple_tag

在app中建立templatetags模塊

建立任意名字的.py文件

!/usr/bin/env python
coding:utf-8

from django import template
from django.utils.safestring import makesafe
from django.template.base import resolve_variable,Node,TemplateSyntaxError
register = template.Libary()
@register.simple_tag
def my_simple_time(a1,a2,a3):
    return a1+a2+a3
@register.simple_tag
def my_input(id,arg):
    result = "    "%(id,arg)
    return mark_safe(result)

在使用自定義simple_tag的html文件中導入以前建立任意名字的.py文件

{% load xx %}
//使用simple_tag
{% my_simple_time 123 %}

在settings中配置當前app,否則django沒法找到自定義的simple_tag

INSTALLED_APPS = (
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'app01',
)

Models層

Django提供了一個抽象層(Model)的構建和管理Web應用程序的數據

每一個模型是一個python類,子類 django.db.models.model

模型中的每一個屬性表明數據庫中的一個字段。

例子:

from django.db import models
class Person(models.Model):
    first_name = models.CharField(max_length=30)
    last_name = models.CharField(max_length=30)

參數與字段

models.AutoField
#自增=int(11),若是沒有的化,默認會生成一個名稱爲id的列,若是要顯示的自定義的一個自增列,必須將給列設置爲主鍵,主鍵設置方式:primary_key=True
models.CharField
#字符串字符段,必須有max_length參數
models.BooleanField
#布爾類型=tinyint(1),不能爲空,Blank=True
models.ComaSeparatedlntegerField
#用逗號分隔的數字=varchar,繼承CharField,因此必須max_length參數
models.DateField
#日期類型 date,對於參數,auto_now=True則每次更新都會更新這個事件,auto_now_add則只是第一次建立添加,以後的更新再也不改變
models.DateTimeField
#日期類型 datetime 同DateField參數同樣
models.Decimal
#十進制小數類型=decimal,必須制定整數位max_digits和小數位decimal_places
models.EmailField
#字符串類型(正則表達式郵箱)=varchar,對字符串進行正則表達式
models.FloatField
#浮點類型=double
models.IntegerField
#整型
models.BigIntegerField
#長整型
integer_field_ranges = {
    'SmallIntegerField': (-32768, 32767),
    'IntegerField': (-2147483648, 2147483647),
    'BigIntegerField': (-9223372036854775808, 9223372036854775807),
    'PositiveSmallIntegerField': (0, 32767),
    'PositiveIntegerField': (0, 2147483647),
  }
models.IPAddressField
#字符串類型(ipv4正則表達式)
models.GenericIPAddressField
#字符串類型(ipv4和ivp6是可選的),參數protocol能夠是:both、ipv、ipv6,驗證時,會根據設置報錯
models.NullBooleanField
#容許爲空的布爾類型
models.PositivenlntegerField
#正integer
models.PositiveSmallIntegerField
#正smallinteger
models.SlugField
#減號、下劃線、字母、數字
models.SmallInterField
#數字,數據庫中的字段有:tinyint、smallint、int、bigint
models.TextField
#字符串=longtext
models.TimeField
#時間 HH:MM[:ss[.uuuuuuu]]
models.URLField
#字符串,地址正則表達式
models.BinaryField
#二進制
models.ImageField
#圖片
models.FilePathField
#文件
null=True
#數據庫中字段是否能夠爲空
blank=True
#django的Admin中添加數據是是否容許空值
primary_key=False
#主鍵,對AutoField設置主鍵後,就會代替原來的自增id列
auto_now
#自動建立,不管添加或修改,都是當前操做的時間
auto_now_add
#自動建立愛你,永遠是建立時的時間
choices
#choices例子
GENDER_CHOICE = (
(u'M',u'Male'),
(u'F',u'Female'),
)
gender = models.CharField(max_length=2,choices=GENDER_CHOICE)
max_length
default
#默認值
verbose_name
#Admin中字段的顯示名稱
nameidb_column
#數據庫中的字段名稱
unique=True
#不容許重複
db_index=True
#數據庫索引
editable=True
#在Admin裏是否可編輯
error_messages=None
#錯誤提示
auto_created=False
#自動建立
相關文章
相關標籤/搜索