1. 程式人生 > >Django-Python重量級Web框架

Django-Python重量級Web框架

Django是一套完整的MVC開發架構,雖然在微服務盛行的今時今日再談MVC有些老土,不過對於python這種解決小專案的開發語言來說,MVC仍然是最優的選擇。

嚴格來說,DjangoMTC,因為其表現層用的是模板(Template

 

Django的目錄結構

manage.py:Django的命令列工具,可以讓我們通過命令形式與Django進行互動。

templates:前臺模板檔案存放的目錄,該目錄有時也會放在專案mysite目錄的裡面,是在settings.py中配置的。

urls.py:路由資訊,配置了url地址與程式碼的對映關係,像Java中的Struts

的配置,小型專案一般一個路由配置檔案就夠了,大型的專案會配置多級路由。

wsgi.py: WSGI 相容的Web 伺服器的入口,以便執行你的專案

 

這裡著重要了解下settings.py中的一些配置:

ROOT_URLCONF = 'mysite.urls'
對應路由資訊第一級的入口,對於路由多級及詳細配置,下面會解釋

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, 'mysite/templates')],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]
這個是配置模板資訊的,特別需要注意DIRS這個配置,代表著模板存放的位置,所以前面提到過templates目錄的位置是可以自己按照習慣自定義的,當然必須要與這個配置匹配。
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'HOST': '',
        'NAME': 'mysite_dev',
        'USER': '',
        'PASSWORD': '',
    }
}
持久層資料庫的配置資訊,用於資料庫連線


STATICFILES_DIRS = (
    os.path.join(BASE_DIR, '/mysite/static'),
)
STATIC_URL = '/static/'
Js、css、圖片等靜態檔案配置,dirs配置的是靜態檔案存放的位置,url配置的是請求靜態檔案的url字首

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    # 'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
中介軟體的配置,相當於java的spring中的AOP,前置加強、後置加強、迴圈加強、異常加強等。

 
INSTALLED_APPS = [
    'mysite.apps.job',
    'mysite.apps.product',
    'mysite.apps.plan',
]

一組業務的MVCDjango中被稱為一個appINSTALLED_APPS配置的就是裝在了哪些app,一個app的目錄結構如下:

apps.py:程式碼很簡單,為了完成app的宣告:

from django.apps import AppConfig


class TemplateConfig(AppConfig):
    name = 'cloudm.apps.plan'

models.py是持久層ormapping的程式碼,後面會詳細介紹

urls.py是路由的詳細配置資訊,後面會詳細介紹

view.py是屬於buusiness層的程式碼,接收頁面的request,處理業務邏輯,呼叫持久層入庫操作結果,返回response給到前臺,這個後面也會詳細介紹。

 

 

 

路由控制URL

urls.py是整個Django專案的筋絡,也是每個app的門戶。前面settings中已經介紹了DITS裡配置的是路由的總入口,以2層路由為例,看下路由的配置資訊。

第一層:
urlpatterns = [
    url(r'^$', views.index),
    url(r'^job/', include("mysite.apps.job.urls")),
    url(r'^product/', include("mysite.apps.product.urls")),
    url(r'^template/', include("mysite.apps.template.urls")),
    url(r'^plan/', include("mysite.apps.plan.urls")),
]

很好理解,根據第一層url的不同引入後續的urls

 

第二層,以plan為例:
urlpatterns = [
    url(r'^$', views.index, name='plan-views-index'),
    url(r'^name/?$', views.create, name='plan-views-name'),
    url(r'^add_plan/?$', views.add_plan, name='plan-views-add'),
    url(r'^add_component/?$', views.add_component, name='plan-views-add-component'),
    url(r'^edit_component/(?P<plan_id>\d+)/?$', views.edit_component, name='plan-views-edit-component'),
    url(r'^edit/(?P<id>\d+)/?$', views.edit, name='plan-views-edit'),
    url(r'^detail/(?P<plan_id>\d+)/?$', views.detail, name='plan-views-detail'),
    url(r'^update_comp/?$', views.update_component, name='plan-views-update-component'),
    url(r'^delete_comp/?$', views.delete_component, name='plan-views-delete-component'),
]

每條配置有3部分,左邊部分是url的內容,中間部分對應業務邏輯層views.py中的具體函式,右邊部分是在該地址在Django專案中的唯一標識,內部可以直接請求這個標識而不是url發起業務請求。

 

 

 

Model

django中遵循 CodeFrist 的原則,程式碼既資料,可以通過python manage.py migrate將改動更新到資料庫。對於Java開發者理解的ORMapping來說,先建表,然後基於表寫模型程式碼和ORMapping的配置檔案。而對於Python開發者來說,模型程式碼就是表結構本身,寫程式碼的過程是直接建表的過程,而不是對映的過程。

看下planmodels.py
from django.db import models

class Plan(models.Model):
    id = models.BigAutoField(primary_key=True)
    detail = models.TextField(blank=True, null=True)
    create_time = models.DateTimeField(auto_now_add=True)
    update_time = models.DateTimeField(auto_now=True)
    status = models.CharField(max_length=10, blank=True, null=True)
    name = models.CharField(max_length=40, blank=True, null=True)

    class Meta:
        managed = True
        db_table = 'plan'
效果圖:

models定義了很多種屬性,涵蓋了關係型資料庫中的所有型別。

看下幾種常用的屬性:

models.BigAutoField:自增長列,一般用於主鍵
models.CharField:最常用的,需要定義長度;
models.BooleanField:布林型別
models.DateField:日期型別,auto_now代表每次更新是否設定為當前時間,auto_now_add代表只有第一次建立時會設定為當前時間。這兩個入參很明顯一個用在createDate場景,一個用在updateDate場景。
models.Decimal:必須設定精度
models.IntegerField:整型
models.TextField:大文字型別
models.BinaryField:大二進位制型別
每個model還定義了一個元資料資訊:
db_table:對應在資料庫中的表名
managed:是否被python manage.py來管理
index_together:聯合索引
unique_together:聯合唯一約束

ORMpping中最難掌握的也是唯一的難點,就是Relationship,這裡只介紹常用的多對一和多對多。Django中處理多對一的關鍵字是ForeignKey,同理多對多也是通過橋表來轉化成2個多對一。

假設我的任務表叫job,代表每個需要執行的任務。任務不見得每次都能執行成功而且可以重複執行,所以給執行結果儲存在job_history中,這樣1job就對應多個job_history,每個job_history通過foreignkeyjob關聯。

Job_History的核心程式碼如下:

class JobHistory(models.Model):
    job = models.ForeignKey('Job', models.DO_NOTHING)

其中foreignkey配置的是model的名字,但是在資料庫層對應的是modelid。第二個引數代表job刪除時關係如何維護,可選項有:

- models.CASCADE,刪除關聯資料,與之關聯也刪除 
- models.DO_NOTHING,刪除關聯資料,引發錯誤IntegrityError 
- models.PROTECT,刪除關聯資料,引發錯誤ProtectedError 
- models.SET_NULL,刪除關聯資料,與之關聯的值設定為null(前提FK欄位需要設定為可空) 
- models.SET_DEFAULT,刪除關聯資料,與之關聯的值設定為預設值(前提FK欄位需要設定預設值) - models.SET,刪除關聯資料,
多對多可以拆解成2個多對一,假設操作人userjob是多對多的關係,一個job可以被多人經手操作,同理一個人可能參與多個job,我們可以建立一個user2jobmodel
class User2Job(models.Model):
    job = models.ForeignKey('Job', models.DO_NOTHING)
user= models.ForeignKey('User', models.DO_NOTHING)
class Meta:
unique_together = ("job","user")

Django對多對多還提供了ManyToManyField這種方式,我自己傾向於拆解。

 

增刪改查:

Object.save()其實是saveOrUpdate()object.delete()是刪除,所以模型的增刪改查就剩下查詢比較複雜了。

常用的查詢方式有:

Get:直接通過條件獲取確定的model物件,例如:

resource = Resource.objects.get(id=resource_id)

Filter:相當於where條件過濾

resource = Resource.objects.filter(job_id=job_id,type_id=1).first()

查詢後跟.count()是取總數,不帶任何條件直接.all()是取全部,.order_by是按屬性排序

批量刪除:

Application.objects.filter(id=data['app_id']).delete()

範圍查詢:

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

id小於1切大於10

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

id not in [11,22,33]

 

關於Django的模型先介紹到這裡,注意:每個app的模型定義的python檔名是models而不是model,也就是說並不是每張表結構建立一個app,我們要把多個相關的模型定義在一個模型檔案中,views.pyurls.py同理,那麼問題來了,哪些表屬於同一個app?這就涉及到軟體開發設計領域的另一個課題DDD(領域驅動設計),建議大家學習掌握。

 

 

View層:

View要做的事情主要有2部分,第一、處理頁面的requestresponse,第二、組織業務邏輯並呼叫持久層(models)。對持久層的操作就是增刪改查,對於業務邏輯的程式設計那就是跟自己業務相關的了,沒什麼好介紹的,那麼View層唯一需要掌握的就剩下RequestResponse了。

View層函式入參是request,代表客戶端傳來的請求,我們需要根據http的具體請求方法(getpostput等)來選擇如何獲取request中的內容。

Response一般分直接返回Json和返回頁面2種。

返回Json
return JsonResponse(ret)
返回頁面:
return render(request, "job/index.html", {'jobs': jobs})

obs”job/index.html”這個前臺頁面需要載入的變數內容。
 
 
Template層:
這一層是概念理解上最簡單,但是後期工作量最大的一層。核心思想就是block,利用模板的繼承,前面flask有類似的使用,這裡也不再詳細描述了。

 

 

最後看下Django的常用命令:

python manage.py migrate

前面已經介紹過了,是models與資料庫的同步命令。

 

python manage.py runserver ip:port

是專案的啟動命令,ip:port是接收服務的地址,一般配置為0:8000

 

python manage.py createsuperuser

建立超級管理員