Part17 - Django

本節內容

  1. Web框架本質
  2. Django 基礎
  3. Django 進階

1、Web框架本質

對於全部的Web應用,本質上其實就是一個socket服務端,用戶的瀏覽器其實就是一個socket客戶端。
WEB框架本質是一個socket
#########WEB框架(代碼文件結構)
MVC
    Model        View        Controller
    數據庫       模板文件    業務處理

MTV
    Model        Template    View
    數據庫        模板文件    業務處理

############## WEB:MVC、MTV

一、本質

import socket

#WEB框架本質-->socket

def handle_request(client):
    buf = client.recv(1024)
    client.send(b"HTTP/1.1 200 OK\r\n\r\n")
    client.send(b"Hello, Seven")


def main():
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.bind(('localhost', 8000))
    sock.listen(5)

    while True:
        connection, address = sock.accept()
        handle_request(connection)
        connection.close()

if __name__ == '__main__':
    main()

二、自定義Web框架

WSGI(Web Server Gateway Interface)是一種規範,它定義了使用python編寫的web app與web server之間接口格式,實現web app與web server間的解耦。 Python標準庫提供的獨立WSGI服務器稱爲wsgiref(封裝好的socket)。
經過Python標準庫提供的wsgiref模塊開發一個本身的Web框架。
 1 from wsgiref.simple_server import make_server  2 from Controller import accout  3 
 4 URL_DICT = {  5         '/index': accout.handle_index,  6         '/data': accout.handle_data,  7     } #能夠作正則匹配,匹配一類的請求內容
 8 
 9 def RunServer(environ, start_response): 10     # environ 客戶端發來的全部數據
11     # start_response 封裝要返回給用戶的數據,響應頭狀態
12     start_response('200 OK', [('Content-Type', 'text/html')]) 13     current_url = environ['PATH_INFO'] 14 
15     # 返回的內容
16     func = None 17     if current_url in URL_DICT: 18         func = URL_DICT[current_url] 19         if func: 20             return func() 21         else: 22             return ['<h1>404</h1>'.encode('utf-8'), ] 23     else: 24         return ['<h1>404</h1>'.encode('utf-8'), ] 25 
26     # if current_url == '/index':
27     # return handle_index()
28     # elif current_url == '/data':
29     # return handle_data()
30     # else:
31     # return ['<h1>404</h1>'.encode('utf-8'), ]
32 
33     # return ['<h1>Hello, web!</h1>'.encode('utf-8'),]
34 
35 if __name__ == '__main__': 36     httpd = make_server('', 8000, RunServer) 37     print("Serving HTTP on port 8000...") 38     httpd.serve_forever()
WSGI

2、Django基礎

Python的WEB框架有Django、Tornado、Flask 等多種,Django相較與其餘WEB框架其優點爲:大而全,框架自己集成了ORM、模型綁定、模板引擎、緩存、Session等諸多功能。
Django生存週期:

 1 Django:用Python開發Web站點提供最齊全的Web框架,基於MTV的框架  2 
 3 pip3 install django  4 
 5 
 6 C:\Python35\Scripts  7 
 8 1、建立Django工程(可使用Pycharm建立)  9     django-admin startproject 【工程名稱】        --> 會在當前目錄下生成Django工程目錄  10     如:django-admin startproject mysite  11  默認建立以下內容  12  mysite  13             - mysite # 對整個程序進行配置  14                 - init  15                 - settings # 配置文件  16                 - url # URL對應關係  17                 - wsgi      # 遵循WSIG規範,uwsgi + nginx(Django內部沒有包含socket)  18                 
 19             - manage.py # 管理Django程序:  20                 - python manage.py  21                 - python manage.py startapp xx  22                 - python manage.py makemigrations  23                 - python manage.py migrate  24 
 25  PS: WSGI (Web Server Gateway Interface)  26  是一種規範,它定義了使用python編寫的web app與web server之間接口格式,實現web app與web server間的解耦。python標準庫提供的獨立WSGI服務器稱爲wsgiref。  27     
 28     
 29 2、運行Django功能(可以使用Pycharm運行,添加Djangoserver)  30     python manage.py runserver 127.0.0.1:8001
 31 
 32     ------------------
 33  chouti  34         - chouti  35             - 配置  36         - 主站 app  37         - 後臺管理 app  38     ------------------
 39 
 40 
 41 3、建立app(進入Django工程根目錄,執行以下命令)  42  python manage.py startapp cmdb  43  python manage.py startapp openstack  44  python manage.py startapp xxoo....  45     
 46  業務處理代碼放入app中(views)  47  app:  48  migrations 修改表結構記錄  49  admin Django爲咱們提供的後臺管理  50  apps 配置當前app  51  models ORM,寫指定的類 經過命令能夠建立數據庫結構  52  tests 單元測試  53  views 業務代碼  54 
 55 4、配置(project.settings.py)  56 
 57  a、配置模板的路徑  58     
 59         TEMPLATES = [  60  {  61                     'BACKEND': 'django.template.backends.django.DjangoTemplates',  62                     
 63                     'DIRS': [os.path.join(BASE_DIR, 'templates')],  64                     
 65                     'APP_DIRS': True,  66                     'OPTIONS': {  67                         'context_processors': [  68                             'django.template.context_processors.debug',  69                             'django.template.context_processors.request',  70                             'django.contrib.auth.context_processors.auth',  71                             'django.contrib.messages.context_processors.messages',  72  ],  73  },  74  },  75  ]  76             
 77  b、配置靜態目錄(不要忘記逗號)  78         static        --> 靜態文件目錄名字使用static  79     
 80         STATICFILES_DIRS = (  81             os.path.join(BASE_DIR, 'static'),  82  )  83 
 84         <link rel="stylesheet" href="/static/commons.css" />
 85         
 86         
 87  c、CSRF verification failed. Request aborted 報錯解決(settings文件內註釋csrf)  88     
 89         MIDDLEWARE = [  90         'django.middleware.security.SecurityMiddleware',  91         'django.contrib.sessions.middleware.SessionMiddleware',  92         'django.middleware.common.CommonMiddleware',  93         #'django.middleware.csrf.CsrfViewMiddleware',  94         'django.contrib.auth.middleware.AuthenticationMiddleware',  95         'django.contrib.messages.middleware.MessageMiddleware',  96         'django.middleware.clickjacking.XFrameOptionsMiddleware',  97  ]  98         
 99 5、定義路由規則 100  url.py 101     
102         "login" --> 函數名 103         
104         
105 6、定義視圖函數 106  app下views.py 107         
108  def func(request): 109             # request.method   GET / POST        -- 用戶提交方式 110             
111             # http://127.0.0.1:8009/home?nid=123&name=alex
112             # request.GET.get('',None) # 獲取請求發來的而數據 113             
114             # request.POST.get('',None) 115                             
116             # return HttpResponse("字符串")        -- 返回字符串 117             # return render(request, "HTML模板的路徑")    -- 返回給用戶模板 118             # return redirect('/只能填URL')        -- 跳轉,只能填'/URL'
119             
120 7、模板渲染 121  特殊的模板語言 122     
123  a、{{ 變量名 }} 124         
125  視圖函數: 126  def func(request): 127             return render(request, "index.html", {'current_user': "alex"}) 128 
129             
130  模板:index.html 131         -----------
132         <html>
133  .. 134             <body>
135                 <div>{{current_user}}</div>
136             </body>
137         
138         </html>
139         
140         ====> 最後生成的字符串 141         
142         <html>
143  .. 144             <body>
145                 <div>alex</div>
146             </body>
147         
148         </html>
149         ------------
150         
151  b、For循環 152  def func(request): 153             return render(request, "index.html", {'current_user': "alex", 'user_list': ['alex','eric']}) 154 
155             
156  index.html 157         ------------
158         <html>
159  .. 160             <body>
161                 <div>{{current_user}}</div>
162                 
163                 <ul>
164                     {% for row in user_list %} 165                     
166                         {% if row == "alex" %} 167                             <li>{{ row }}</li>
168                         {% endif %} 169                         
170                     {% endfor %} 171                 </ul>
172                 
173             </body>
174         
175         </html>
176         ------------
177         
178         
179  c、索引################# 180  def func(request): 181             return render(request, "index.html", { 182                         'current_user': "alex", 183                         'user_list': ['alex','eric'], 184                         'user_dict': {'k1': 'v1', 'k2': 'v2'}}) 185 
186             
187  index.html 188         
189         <html>
190  .. 191             <body>
192                 <div>{{current_user}}</div>
193                 
194                 <a> {{ user_list.1 }} </a> #模板語言中根據索引獲取列表內容 195                 <a> {{ user_dict.k1 }} </a> #模板語言中根據索引獲取字典內容 196                 <a> {{ user_dict.k2 }} </a>
197                 
198             </body>
199         
200         </html>
201     
202     
203  d、條件 ################### 204     
205  def func(request): 206             return render(request, "index.html", { 207                         'current_user': "alex", 208                         "age": 18, 209                         'user_list': ['alex','eric'], 210                         'user_dict': {'k1': 'v1', 'k2': 'v2'}}) 211 
212             
213  index.html 214         
215         <html>
216  .. 217             <body>
218                 <div>{{current_user}}</div>
219                 
220                 <a> {{ user_list.1 }} </a>
221                 <a> {{ user_dict.k1 }} </a>
222                 <a> {{ user_dict.k2 }} </a>
223                 
224                 {% if age %} 225                     <a>有年齡</a>
226                     {% if age > 16 %} 227                         <a>老男人</a>
228                     {% else %} 229                         <a>小鮮肉</a>
230                     {% endif %} 231                 {% else %} 232                     <a>無年齡</a>
233                 {% endif %} 234             </body>
235         
236         </html>
Django筆記

一、建立Django工程

可使用Django在命令行中建立工程,也可使用Pycharm建立(本質上自動執行了建立命令)
 1 django-admin startproject 【工程名稱】  2 如:django-admin startproject mysite  3  默認建立以下內容  4  - mysite # 工程  5         - mysite # 對整個程序進行配置  6             - __init__.py  7             - settings.py # 配置文件  8             - urls.py # URL對應關係  9             - wsgi.py # 遵循WSIG規範,wsgi + nginx(Django內部沒有包含socket) 10             
11         - manage.py # 管理Django程序: 12             - python manage.py 13             - python manage.py startapp xx 14             - python manage.py makemigrations 15             - python manage.py migrate 16 
17 PS: WSGI(Web Server Gateway Interface)是一種規範,它定義了使用python編寫的web app與web server之間接口格式,實現web app與web server間的解耦。python標準庫提供的獨立WSGI服務器稱爲wsgiref。
View Code

二、運行Django功能

能夠在命令行中啓動,也可使用Pycharm建立Django server來運行(在Pycharm中建立的Django工程默認添加了Django server)
 1 python manage.py runserver 127.0.0.1:8001
 2 
 3 ------------------
 4 chouti  5     - chouti  6         - 配置  7     - 主站 app  8     - 後臺管理 app  9 ------------------
10 
11 PS:Python和Django要加環境變量
在命令行中啓動

三、建立app

進入Django工程根目錄,執行以下命令
 1 python manage.py startapp cmdb  2 python manage.py startapp openstack  3 python manage.py startapp xxoo....  4 
 5 業務處理代碼放入app中(views)  6 app:  7  migrations 修改表結構記錄  8  admin Django爲咱們提供的後臺管理  9  apps 配置當前app 10  models ORM,寫指定的類 經過命令能夠建立數據庫結構 11  tests 單元測試 12     views          業務代碼
View Code

四、配置文件

""" Django settings for s14django project. Generated by 'django-admin startproject' using Django 1.10.4. For more information on this file, see https://docs.djangoproject.com/en/1.10/topics/settings/ For the full list of settings and their values, see https://docs.djangoproject.com/en/1.10/ref/settings/ """

import os # Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) # Quick-start development settings - unsuitable for production # See https://docs.djangoproject.com/en/1.10/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'hut(bs^o50n^opj8yneen_sh)m0uvu#sdzr%&eq1x)5p*(tqcz'

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True ALLOWED_HOSTS = [] # Application definition
 INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'cmdb', ] 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', ] ROOT_URLCONF = 's14django.urls' TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [os.path.join(BASE_DIR, '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', ], }, }, ] WSGI_APPLICATION = 's14django.wsgi.application'


# Database # https://docs.djangoproject.com/en/1.10/ref/settings/#databases
 DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), } } # Password validation # https://docs.djangoproject.com/en/1.10/ref/settings/#auth-password-validators
 AUTH_PASSWORD_VALIDATORS = [ { 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', }, { 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', }, { 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', }, { 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', }, ] # Internationalization # https://docs.djangoproject.com/en/1.10/topics/i18n/
 LANGUAGE_CODE = 'en-us' TIME_ZONE = 'UTC' USE_I18N = True USE_L10N = True USE_TZ = True # Static files (CSS, JavaScript, Images) # https://docs.djangoproject.com/en/1.10/howto/static-files/
 STATIC_URL = '/static/'

# 配置好static靜態文件目錄,不配置用戶訪問頁面靜態文件訪問不到
STATICFILES_DIRS = ( os.path.join(BASE_DIR, 'static'), ) # APPEND_SLASH=True
settings.py
1) 配置HTML模板的路徑
TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [os.path.join(BASE_DIR, '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', ], }, }, ]
View Code
2) 配置靜態目錄
static        --> 靜態文件目錄名字使用static STATICFILES_DIRS = ( os.path.join(BASE_DIR, 'static'), ) <link rel="stylesheet" href="/static/commons.css" />
CSS、JS、圖片等靜態文件目錄
3) CSRF verification failed. Request aborted 報錯解決
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', ]
settings內註釋csrf
4) 數據庫配置
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), } }
默認sqllite
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME':'dbname', 'USER': 'root', 'PASSWORD': 'xxx', 'HOST': '', 'PORT': '', } } # 注意: # 因爲Django內部鏈接MySQL時使用的是MySQLdb模塊,而Python3中還無此模塊,因此須要使用pymysql模塊來代替。
  
# 在project下與其同名文件夾下的 __init__.py文件中作以下設置
  
import pymysql pymysql.install_as_MySQLdb()
MySQL配置

五、路由規則

定義url與業務處理函數(視圖函數)之間的映射關係。
 1 URL拼接傳遞參數有兩種方式:  2     - 在url後加"?key=value"拼接,能夠在視圖函數中經過get()獲取,如:  3  html文件  4             <a class="detail" href="/index?nid=1">詳細信息</a> #id是內置方法,儘可能不要使用id作參數  5         ---
 6  urls.py文件  7             url(r'^index/', views.index), #一個url對應函數  8             url(r'^home/', views.Home.as_view()), #一個url對應類,根據method經過反射來執行對應方法  9         
10             
11     - 在url後加"分隔符value"拼接,在urls.py中經過正則進行匹配(經常使用方法),如: 12  html文件 13             <a class="detail" href="/detail-2-9.html">詳細信息</a>
14         ---    
15  urls.py文件 16             a、一類url對應函數,"正則匹配"的數據(\d+)交給視圖函數(視圖函數參數有位置要求) 17                 url(r'^detail-(\d+)-(\d+).html', views.detail), 18             
19                 def func(request, nid, uid):    #nid即正則匹配的數據(\d+) 20  pass 21                 def func(request, *args): 22                     args = (2,9) 23                 def func(request, *args, **kwargs): 24                     args = (2,9) 25                     
26                     
27             b、"正則匹配"的數據"分組"(?P<nid>\d+)交給視圖函數(視圖函數參數沒有位置要求) 28                 url(r'^detail-(?P<nid>\d+)-(?P<uid>\d+).html', views.detail) 29                 
30  def func(request, nid, uid): 31  pass 32                     
33                 def funct(request, **kwargs): 34                     kwargs = {'nid': 1, 'uid': 3} 35                     
36                 def func(request, *args, **kwargs): 37                     args = (2,9) 38    
39    
40     - PS: 41         def detail(request, *args,**kwargs): 42             pass
路由系統筆記
 1 """s14django URL Configuration  2 
 3 The `urlpatterns` list routes URLs to views. For more information please see:  4  https://docs.djangoproject.com/en/1.10/topics/http/urls/  5 Examples:  6 Function views  7  1. Add an import: from my_app import views  8  2. Add a URL to urlpatterns: url(r'^$', views.home, name='home')  9 Class-based views 10  1. Add an import: from other_app.views import Home 11  2. Add a URL to urlpatterns: url(r'^$', Home.as_view(), name='home') 12 Including another URLconf 13  1. Import the include() function: from django.conf.urls import url, include 14  2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls')) 15 """
16 from django.conf.urls import url 17 from django.contrib import admin 18 from cmdb import views 19 
20 urlpatterns = [ 21     url(r'^admin/', admin.site.urls), 22     # url(r'^h.html/', views.home),
23     url(r'^login', views.login), 24     url(r'^home', views.home), 25 ]
urls.py
1) 單一路由對應
from django.conf.urls import url urlpatterns = [ url(r'^index/', views.index),    #一個url對應函數
    url(r'^home/', views.Home.as_view()),    #一個url對應類,根據method經過反射來執行對應方法
]
urls.py
from django.views import View class Home(View): #方法名必須小寫,支持的方法見源碼
    def dispatch(self, request, *args, **kwargs): # 調用父類中的dispatch,至關於裝飾器功能
        print('before') result = super(Home,self).dispatch(request, *args, **kwargs) print('after') return result def get(self,request): print(request.method) return render(request, 'home.html') def post(self,request): print(request.method,'POST') return render(request, 'home.html')
views.py(一個url對應一個類)
2) 基於正則的路由
 1 html文件  2     <a class="detail" href="/detail-2-9.html">詳細信息</a>
 3 ---    
 4 urls.py文件  5     a、一類url對應函數,"正則匹配"的數據(\d+)交給視圖函數(視圖函數參數有位置要求)  6         url(r'^detail-(\d+)-(\d+).html', views.detail),  7     
 8         def func(request, nid, uid):    #nid即正則匹配的數據(\d+)  9  pass 10         def func(request, *args): 11             args = (2,9) 12         def func(request, *args, **kwargs): 13             args = (2,9) 14             
15             
16     b、"正則匹配"的數據"分組"(?P<nid>\d+)交給視圖函數(視圖函數參數沒有位置要求) 17         url(r'^detail-(?P<nid>\d+)-(?P<uid>\d+).html', views.detail) 18         
19  def func(request, nid, uid): 20  pass 21             
22         def funct(request, **kwargs): 23             kwargs = {'nid': 1, 'uid': 3} 24             
25         def func(request, *args, **kwargs): 26             args = (2,9)
View Code
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style> body{ margin: 0;
        } .menu{ display: block; padding: 5px;

        }
    </style>
</head>
<body>
    <div style="height: 48px;background-color: black;color: white"> 紅紅火火哈哈 </div>
    <div>
        <div style="position: absolute;top:48px;bottom: 0;left: 0;width: 200px;background-color: brown;">
            <a class="menu" href="/cmdb/user_info/">用戶管理</a>
            <a class="menu" href="/cmdb/user_group/">用戶組管理</a>
        </div>
        <div style="position:absolute;top:48px;left: 210px;bottom: 0;right: 0;overflow: auto">
            <h3>添加用戶</h3>
            <form method="POST" action="/cmdb/user_info/">
                <input type="text" name="user" />
                <input type="text" name="pwd" />
                <select name="group_id"> {% for item in group_list %} <option value="{{ item.uid }}">{{ item.caption }}</option> {% endfor %} </select>
                <input type="submit" value="添加"/>
            </form>
            <h3>用戶列表</h3>
            <ul> {% for row in user_list %} <li>
                        <a href="/cmdb/userdetail-{{ row.id }}/">{{ row.username }}</a> | <span> {{ row.user_group.caption }} </span>
                        <a href="/cmdb/userdel-{{ row.id }}/">刪除</a> | <a href="/cmdb/useredit-{{ row.id }}/">編輯</a>
                    </li> {% endfor %} </ul>
        </div>
    </div>
</body>
</html>
示例HTML
3) 多級路由(include),根據app對路由規則進行分類
#project/urls.py
from django.conf.urls import url,include from django.contrib import admin urlpatterns = [ url(r'^cmdb/', include("app01.urls")), url(r'^monitor/', include("app02.urls")), ] #app01/urls.py
from django.conf.urls import url,include from django.contrib import admin from app01 import views urlpatterns = [ url(r'^login/', views.login), ] #app02/urls.py
from django.conf.urls import url,include from django.contrib import admin from app02 import views urlpatterns = [ url(r'^login/', views.login), ]
View Code
4) 默認值

 

5) 命名空間

 

六、視圖函數

處理用戶請求函數,app目錄下的views.py
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body> {#上傳文件form作處理enctype="multipart/form-data"#} <form action="/login/" method="POST" enctype="multipart/form-data">
        <p>
            <input type="text" name="user" placeholder="用戶名" />
        </p>
        <p>
            <input type="password" name="pwd" placeholder="密碼" />
        </p>
        <p> 男:<input type="radio" name="gender" value="1"/> 女:<input type="radio" name="gender" value="2"/>
        </p>
        <p> 男:<input type="checkbox" name="favor" value="11"/> 女:<input type="checkbox" name="favor" value="22"/>
        </p>
        <p>
            <select name="city" multiple>
                <option value="sh">上海</option>
                <option value="bj">北京</option>
                <option value="tj">天津</option>
            </select>
        </p>
        <p>
            <input type="file" name="fafafa"/>
        </p>

        <input type="submit" value="提交"/>
    </form>
</body>
</html>
示例HTML
1) 基本用法(一個url對應一個函數,一個url對應類的參照5-1)
 1 app下views.py  2     
 3  def func(request):  4         # request.method   GET / POST        -- 用戶提交方式  5         
 6         # http://127.0.0.1:8009/home?nid=123&name=alex
 7         # request.GET.get('',None) # 獲取請求發來的而數據  8         
 9         # request.POST.get('',None) 10                         
11         # return HttpResponse("字符串")        -- 返回字符串 12         # return render(request, "HTML模板的路徑")    -- 返回給用戶模板 13         # return redirect('/只能填URL')        -- 跳轉,只能填'/URL'
View Code
 1 from django.shortcuts import render  2 
 3 # Create your views here.
 4 from django.shortcuts import HttpResponse  5 from django.shortcuts import render  6 from django.shortcuts import redirect  7 
 8 def login(request):  9     # 包含用戶提交的全部信息
10     # print(request.method) # 獲取用戶提交方法
11     error_msg = ""
12     #若是請求提交的方法是POST(用戶提交的數據)
13     if request.method == "POST": 14         # 獲取用戶經過POST提交過來的數據(用戶提交的數據相似於字典)
15         user = request.POST.get('user',None)    #get('user',None)獲取user內容,默認爲None
16         pwd = request.POST.get('pwd',None) 17         if user == 'root' and pwd == "123": 18             # 去跳轉到
19             return redirect('/login')   #redirect重定向、跳轉
20         else: 21             # 用戶密碼不配
22             error_msg = "用戶名或密碼錯誤"
23     #打開頁面並返回給用戶,settings文件中配置了html文件的路徑TEMPLATES('DIRS': [os.path.join(BASE_DIR, 'templates')])
24     return render(request,'login.html', {'error_msg': error_msg})   #render找到模板返回給用戶
25 
26 USER_LIST = [ 27     {'id': 1, 'username': 'alex', 'email': 'asdfasdf', "gender": ''}, 28     {'id': 2, 'username': 'eriuc', 'email': 'asdfasdf', "gender": ''}, 29     {"id": 3,'username': 'seven', 'email': 'asdfasdf', "gender": ''}, 30 ] 31 
32 def home(request): 33     print(request.GET.get('nid')) 34 
35     if request.method == "POST": 36         # 獲取用戶提交的數據 POST請求中
37         u = request.POST.get('username') 38         e = request.POST.get('email') 39         g = request.POST.get('gender') 40         temp = {'username': u, 'email': e, "gender": g} 41  USER_LIST.append(temp) 42     return render(request, 'test/home.html', {'user_list': USER_LIST}) 43 
44 
45 # def login(request):
46 # # string = """
47 # # <form>
48 # # <input type='text' />
49 # # </form>
50 # #
51 # # """
52 # # f = open('templates/login.html', 'r', encoding='utf-8')
53 # # data = f.read()
54 # # f.close()
55 # # return HttpResponse(data)
56 # return render(request,'login.html')
57 
58 # def home(request):
59 # return HttpResponse('<h1>CMDB</h1>')
60 
61 # 主機管理
62 # 防火牆
63 # 。。。
views.py
2) 獲取用戶請求數據
request.GET.get()
request.POST.get()
request.FILES.get()
PS:
    GET:http請求默認使用的method,獲取數據                
    POST:能夠與GET區分,用來提交數據
3) 獲取多選的內容(checkbox等)
request.POST.getlist()
4) 上傳文件
import os from django.shortcuts import render,redirect from django.core.files.uploadedfile import InMemoryUploadedFile def login(request): if request.method == "GET": return render(request, 'login.html') elif request.method == "POST": # 上傳文件,form標籤作特殊設置
        obj = request.FILES.get('fafafa') print(obj,type(obj),obj.name) #文件路徑拼接
        file_path = os.path.join('upload', obj.name) # 打開文件
        f = open(file_path, mode="wb") # obj.chunks()上傳文件的塊數據
        for i in obj.chunks(): f.write(i) f.close() return render(request, 'login.html') else: # PUT,DELETE,HEAD,OPTION...
        return redirect('/index/') 
views.py
5) FBV&CBV
FBV --> function base view url.py /index/ -> 函數名 view.py def 函數(request): ... CBV --> class base view url.py /index/ -> 類 urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^home/', views.Home.as_view()), #根據get或post提交方式在類中執行對應的方法 ] view.py from django.views import View class Home(View): def dispatch(self, request, *args, **kwargs): # 調用父類中的dispatch print('before') result = super(Home,self).dispatch(request, *args, **kwargs) print('after') return result def get(self,request): print(request.method) return render(request, 'home.html') def post(self,request): print(request.method,'POST') return render(request, 'home.html') PS:類的方法名必定要小寫,源代碼中定義好了方法名 ====》 建議:二者都用
View Code
6) 裝飾器

 

七、模板

templates目錄下html
1) 模板的執行
模版的建立過程,其實就是讀取模版(其中嵌套着模版標籤),而後將 Model 中獲取的數據插入到模版中,最後將信息返回給用戶。
2) 模板語言
變量:
        {{ item }}
For循環:
        {% for item in item_list %}  {{ item }}  {% endfor %}
            forloop.counter
            forloop.first
            forloop.last 
if語句:        
        {% if ordered_warranty %}  {% else %} {% endif %}
母板:
        {% block title %}{% endblock %}
子板:
        {% extends "base.html" %}
        {% block title %}{% endblock %}    
幫助方法:
        {{ item.event_start|date:"Y-m-d H:i:s"}}
        {{ bio|truncatewords:"30" }}
        {{ my_list|first|upper }}
        {{ name|lower }}
 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>Title</title>
 6     <link rel="stylesheet" href="/static/commons.css" />
 7     <style>
 8  label{
 9  width: 80px;
10  text-align: right;
11  display: inline-block;
12         }
13     </style>
14 </head>
15 <body>
16  {#提交數據給login#} 17     <form action="/login" method="post">
18         <p>
19  {#點擊label後input內出現光標#} 20             <label for="username">用戶名:</label>
21             <input id="username" name="user" type="text" />
22         </p>
23         <p>
24             <label for="password">密碼:</label>
25             <input id="password" name="pwd" type="password" />
26             <input type="submit" value="提交" />
27  {# Django會特殊處理 {{ error_msg }} #} 28             <span style="color: red;">{{ error_msg }}</span>
29         </p>
30     </form>
31     <script src="/static/jquery.min.js"></script>
32 </body>
33 </html>
變量
 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>Title</title>
 6 </head>
 7 <body style="margin: 0">
 8     <div style="height: 48px;background-color: #dddddd"></div>
 9     <div>
10         <form action="/home" method="post">
11             <input type="text" name="username" placeholder="用戶名" />
12             <input type="text" name="email" placeholder="郵箱"/>
13             <input type="text" name="gender" placeholder="性別"/>
14             <input type="submit" value="添加" />
15         </form>
16     </div>
17     <div>
18         <table>
19  {# Django模板語言for循環 #} 20  {% for row in user_list %} 21                 <tr>
22                     <td>{{ row.username }}</td>
23                     <td>{{ row.gender }}</td>
24                     <td>{{ row.email }}</td>
25                     <td>
26                         <a href="/detail?nid={{ row.id }}">查看詳細</a> | 27                         <a class="del" href="#" row-id="{{ row.id }}">刪除</a>
28                     </td>
29                 </tr>
30  {% endfor %} 31 
32         </table>
33     </div>
34     <div>
35         <form action="/del_host" method="post">
36             <input style="display: none" id="nid" type="text" name="nid" />
37             <p>
38                 <input type="submit" />
39                 <input type="botton" />
40             </p>
41         </form>
42     </div>
43     <script>
44  $('.del').click(function(){ 45             var row_id = $(this).attr('row-id'); 46             //賦值
47  $('#nid').val(row_id); 48  }) 49     </script>
50 </body>
51 </html>
For循環
 1 def func(request):  2     return render(request, "index.html", {  3                 'current_user': "alex",  4                 'user_list': ['alex','eric'],  5                 'user_dict': {'k1': 'v1', 'k2': 'v2'}})  6 
 7     
 8 index.html  9 
10 <html>
11 .. 12     <body>
13         <div>{{current_user}}</div>
14         
15         <a> {{ user_list.1 }} </a> #模板語言中根據索引獲取列表內容 16         <a> {{ user_dict.k1 }} </a> #模板語言中根據索引獲取字典內容 17         <a> {{ user_dict.k2 }} </a>
18         
19     </body>
20 
21 </html>
數據索引
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body> {#根據索引(key)直接獲取值#} {{ user_dict.k1 }} <ul> {#循環的key#} {% for k in user_dict.keys %} <li>{{ k }}</li> {% endfor %} </ul>
    <ul> {#循環的value#} {% for val in user_dict.values %} <li>{{ val }}</li> {% endfor %} </ul>
    <ul> {#循環的key和value#} {% for k,row in user_dict.items %} <li>{{ k }}-{{ row }}</li> {% endfor %} </ul>
</body>
</html>
循環字典
 1 def func(request):  2     return render(request, "index.html", {  3                 'current_user': "alex",  4                 "age": 18,  5                 'user_list': ['alex','eric'],  6                 'user_dict': {'k1': 'v1', 'k2': 'v2'}})  7 
 8     
 9 index.html 10 <html>
11 .. 12     <body>
13         <div>{{current_user}}</div>
14         
15         <a> {{ user_list.1 }} </a>
16         <a> {{ user_dict.k1 }} </a>
17         <a> {{ user_dict.k2 }} </a>
18         
19         {% if age %} 20             <a>有年齡</a>
21             {% if age > 16 %} 22                 <a>老男人</a>
23             {% else %} 24                 <a>小鮮肉</a>
25             {% endif %} 26         {% else %} 27             <a>無年齡</a>
28         {% endif %} 29     </body>
30 
31 </html>
if條件語句
3) 自定義simple_tag

 

八、中間件

 

九、admin

 

3、Django進階

Python的WEB框架有Django、Tornado、Flask 等多種,Django相較與其餘WEB框架其優點爲:大而全,框架自己集成了ORM、模型綁定、模板引擎、緩存、Session等諸多功能。

一、Model

django使用ORM方式處理數據庫相關操做,ORM即,關係對象映射(Object Relational Mapping)。
  PHP:activerecord
  Java:Hibernate 
  C#:Entity Framework
django中遵循 Code Frist 的原則,即,根據代碼中定義的類來自動生成數據庫表。注意原生SQL與ORM的對應關係。
1) 建立表
*基本結構
a. 先寫類 from django.db import models # app01_userinfo
    class UserInfo(models.Model): # id列,自增,主鍵
        # 用戶名列,字符串類型,指定長度
        username = models.CharField(max_length=32) password = models.CharField(max_length=64) b. 註冊APP INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'app01',    #settings中添加app名,Django纔給app生成數據庫
 ] c. 執行命令(同步結構改動到數據庫) #記錄對models.py的改動(表結構變化),並在migrations下生成記錄文件
 python manage.py makemigrations #將改動應用到數據庫
 python manage.py migrate 注意:縮小列長度要謹慎,超出長度數據會丟失 d. ********** 注意 *********** Django默認使用MySQLdb模塊連接MySQL 主動修改成pymysql,在project同名文件夾下的__init__文件中添加以下代碼便可: import pymysql pymysql.install_as_MySQLdb()
建立表基本過程
# Create your models here. # app01_userinfo

from django.db import models class UserGroup(models.Model): uid = models.AutoField(primary_key=True) caption = models.CharField(max_length=32,unique=True) ctime = models.DateTimeField(auto_now_add=True, null=True) uptime = models.DateTimeField(auto_now=True, null=True) class UserInfo(models.Model):   #必須繼承models.Model
    # id列,自增,主鍵 (Djiango默認建立)
    # 用戶名列,字符串類型CharField,指定長度max_length
    # 字符串、數字、時間、二進制
    username = models.CharField(max_length=32,blank=True,verbose_name='用戶名') password = models.CharField(max_length=60, help_text='pwd') email = models.CharField(max_length=60) test = models.EmailField(max_length=19,null=True,error_messages={'invalid': '請輸入密碼'}) # user_group_id 數字
    user_group = models.ForeignKey("UserGroup",to_field='uid',on_delete=models.CASCADE) # (uid,catption,ctime,uptimew)
    user_type_choices = ( (1, '超級用戶'), (2, '普通用戶'), (3, '普普通用戶'), ) user_type_id = models.IntegerField(choices=user_type_choices,default=1) #不一樣的字符串類型(...Field),給Django的admin表單認證使用的
    # test = models.URLField(max_length=19,null=True)
    # test = models.GenericIPAddressField()
    # gender = models.CharField(max_length=60, null=True)
models.py
字符串******** 不一樣的字符串類型,只是給Django的admin表單校驗使用的(如自動校驗EmailField是不是郵箱格式) CharField(Field) - 字符類型 - 必須提供max_length參數, max_length表示字符長度 TextField(Field) - 文本類型 EmailField(CharField): - 字符串類型,Django Admin以及ModelForm中提供驗證機制 IPAddressField(Field) - 字符串類型,Django Admin以及ModelForm中提供驗證 IPV4 機制(新版本中廢棄,使用GenericIPAddressField) GenericIPAddressField(Field) - 字符串類型,Django Admin以及ModelForm中提供驗證 Ipv4和Ipv6 - 參數: protocol,用於指定Ipv4或Ipv6, 'both',"ipv4","ipv6" unpack_ipv4, 若是指定爲True,則輸入::ffff:192.0.2.1時候,可解析爲192.0.2.1,開啓刺功能,須要protocol="both" URLField(CharField) - 字符串類型,Django Admin以及ModelForm中提供驗證 URL SlugField(CharField) - 字符串類型,Django Admin以及ModelForm中提供驗證支持 字母、數字、下劃線、鏈接符(減號) CommaSeparatedIntegerField(CharField) - 字符串類型,格式必須爲逗號分割的數字 UUIDField(Field) - 字符串類型,Django Admin以及ModelForm中提供對UUID格式的驗證 FilePathField(Field) - 字符串,Django Admin以及ModelForm中提供讀取文件夾下文件的功能 - 參數: path, 文件夾路徑 match=None, 正則匹配 recursive=False, 遞歸下面的文件夾 allow_files=True, 容許文件 allow_folders=False, 容許文件夾 FileField(Field) - 字符串,路徑保存在數據庫,文件上傳到指定目錄 - 參數: upload_to = "" 上傳文件的保存路徑 storage = None 存儲組件,默認django.core.files.storage.FileSystemStorage ImageField(FileField) - 字符串,路徑保存在數據庫,文件上傳到指定目錄 - 參數: upload_to = "" 上傳文件的保存路徑 storage = None 存儲組件,默認django.core.files.storage.FileSystemStorage width_field=None, 上傳圖片的高度保存的數據庫字段名(字符串) height_field=None 上傳圖片的寬度保存的數據庫字段名(字符串) 數字******** AutoField(Field) - int自增列,必須填入參數 primary_key=True BigAutoField(AutoField) - bigint自增列,必須填入參數 primary_key=True 注:當model中若是沒有自增列,則自動會建立一個列名爲id的列 ---
        from django.db import models class UserInfo(models.Model): # 自動建立一個列名爲id的且爲自增的整數列
            username = models.CharField(max_length=32) class Group(models.Model): # 自定義自增列
            nid = models.AutoField(primary_key=True) name = models.CharField(max_length=32) SmallIntegerField(IntegerField): - 小整數 -32768 ~ 32767 PositiveSmallIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField) - 正小整數 0 ~ 32767 IntegerField(Field) - 整數列(有符號的) -2147483648 ~ 2147483647 PositiveIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField) - 正整數 0 ~ 2147483647 BigIntegerField(IntegerField): - 長整型(有符號的) -9223372036854775808 ~ 9223372036854775807 自定義無符號整數字段 class UnsignedIntegerField(models.IntegerField): def db_type(self, connection): return 'integer UNSIGNED' PS: 返回值爲字段在數據庫中的屬性,Django字段默認的值爲: 'AutoField': 'integer AUTO_INCREMENT', 'BigAutoField': 'bigint AUTO_INCREMENT', 'BinaryField': 'longblob', 'BooleanField': 'bool', 'CharField': 'varchar(%(max_length)s)', 'CommaSeparatedIntegerField': 'varchar(%(max_length)s)', 'DateField': 'date', 'DateTimeField': 'datetime', 'DecimalField': 'numeric(%(max_digits)s, %(decimal_places)s)', 'DurationField': 'bigint', 'FileField': 'varchar(%(max_length)s)', 'FilePathField': 'varchar(%(max_length)s)', 'FloatField': 'double precision', 'IntegerField': 'integer', 'BigIntegerField': 'bigint', 'IPAddressField': 'char(15)', 'GenericIPAddressField': 'char(39)', 'NullBooleanField': 'bool', 'OneToOneField': 'integer', 'PositiveIntegerField': 'integer UNSIGNED', 'PositiveSmallIntegerField': 'smallint UNSIGNED', 'SlugField': 'varchar(%(max_length)s)', 'SmallIntegerField': 'smallint', 'TextField': 'longtext', 'TimeField': 'time', 'UUIDField': 'char(32)', BooleanField(Field) - 布爾值類型 NullBooleanField(Field): - 能夠爲空的布爾值 DurationField(Field) - 長整數,時間間隔,數據庫中按照bigint存儲,ORM中獲取的值爲datetime.timedelta類型 FloatField(Field) - 浮點型 DecimalField(Field) - 10進制小數 - 參數: max_digits,小數總長度 decimal_places,小數位長度 二進制******** BinaryField(Field) - 二進制類型 日期、時間******** DateTimeField(DateField) - 日期+時間格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ] DateField(DateTimeCheckMixin, Field) - 日期格式      YYYY-MM-DD TimeField(DateTimeCheckMixin, Field) - 時間格式      HH:MM[:ss[.uuuuuu]]
字段類型
auto_now_add 建立時,自動生成時間 auto_now 更新時,自動更新爲當前時間 # obj = UserGroup.objects.filter(id=1).update(caption='CEO') #自動時間更新不生效
    # obj = UserGroup.objects.filter(id=1).first() #生效
    # obj.caption = "CEO"
    # obj.save()
 default 數據庫中字段的默認值 null 數據庫中字段是否能夠爲空 db_column 數據庫中字段的列名 db_tablespace primary_key 數據庫中字段是否爲主鍵 db_index 數據庫中字段是否能夠創建索引 unique 數據庫中字段是否能夠創建惟一索引 unique_for_date 數據庫中字段【日期】部分是否能夠創建惟一索引 unique_for_month 數據庫中字段【月】部分是否能夠創建惟一索引 unique_for_year 數據庫中字段【年】部分是否能夠創建惟一索引 verbose_name Admin中字段名顯示自定義的名字 blank Admin中是否容許用戶輸入爲空 editable Admin中是否能夠編輯 help_text Admin中該字段的輸入提示信息(顯示在該行下邊) choices Admin中顯示選擇框的內容,用不變更的數據放在內存中從而避免跨表操做 注:由於數據存在內存中,若是修改要重啓程序纔會生效 如:gf = models.IntegerField(choices=[(0, '何穗'),(1, '大表姐'),],default=1) error_messages 自定義錯誤信息(字典類型),從而定製想要顯示的錯誤信息; 字典健:null, blank, invalid, invalid_choice, unique, and unique_for_date 如:{'null': "不能爲空.", 'invalid': '格式錯誤'} validators 自定義錯誤驗證(列表類型),從而定製想要的驗證規則 from django.core.validators import RegexValidator from django.core.validators import EmailValidator,URLValidator,DecimalValidator,\ MaxLengthValidator,MinLengthValidator,MaxValueValidator,MinValueValidator 如: test = models.CharField( max_length=32, error_messages={ 'c1': '優先錯信息1', 'c2': '優先錯信息2', 'c3': '優先錯信息3', }, validators=[ RegexValidator(regex='root_\d+', message='錯誤了', code='c1'), RegexValidator(regex='root_112233\d+', message='又錯誤了', code='c2'), EmailValidator(message='又錯誤了', code='c3'), ] )
字段的參數
class UserInfo(models.Model): nid = models.AutoField(primary_key=True) username = models.CharField(max_length=32) class Meta: # 數據庫中生成的表名稱 默認 app名稱 + 下劃線 + 類名
            db_table = "table_name"

            # 聯合索引
            index_together = [ ("pub_date", "deadline"), ] # 聯合惟一索引
            unique_together = (("driver", "restaurant"),) # admin中顯示的表名稱
 verbose_name # verbose_name加s
 verbose_name_plural #更多:https://docs.djangoproject.com/en/1.10/ref/models/options/
元信息(models.py)
1.觸發Model中的驗證和錯誤提示有兩種方式: a. Django Admin中的錯誤信息會優先根據Admiin內部的ModelForm錯誤信息提示,若是都成功,纔來檢查Model的字段並顯示指定錯誤信息 b. 調用Model對象的 clean_fields 方法,如: # models.py
            class UserInfo(models.Model): nid = models.AutoField(primary_key=True) username = models.CharField(max_length=32) email = models.EmailField(error_messages={'invalid': '格式錯了.'}) # views.py
            def index(request): obj = models.UserInfo(username='11234', email='uu') try: print(obj.clean_fields()) except Exception as e: print(e) return HttpResponse('ok') # Model的clean方法是一個鉤子,可用於定製操做,如:上述的異常處理。

    2.Admin中修改錯誤提示 # admin.py
        from django.contrib import admin from model_club import models from django import forms class UserInfoForm(forms.ModelForm): username = forms.CharField(error_messages={'required': '用戶名不能爲空.'}) email = forms.EmailField(error_messages={'invalid': '郵箱格式錯誤.'}) age = forms.IntegerField(initial=1, error_messages={'required': '請輸入數值.', 'invalid': '年齡必須爲數值.'}) class Meta: model = models.UserInfo # fields = ('username',)
                fields = "__all__"


        class UserInfoAdmin(admin.ModelAdmin): form = UserInfoForm admin.site.register(models.UserInfo, UserInfoAdmin)
拓展知識

 

*連表結構

 

2) 操做表
*基本操做
根據類對數據庫表中的數據進行各類操做

    一對多:
    
        a. 建立外鍵(一個對象)
        
        b. 數據庫中實際存儲 --> 外鍵字段_id
        
        c.    根據"外鍵字段_id"添加數據
            models.tb.object.create(name='root', user_group_id=1)
            
        d.  顯示用戶組信息
            
            userlist = models.tb.object.all()
            for row in userlist:
                row.id
                row.user_group_id
                row.user_group.caption

 

*進階操做

 

*其餘操做

 

*連表操做

 

*擴展

 

二、Form

 

三、跨站請求僞造

 

四、Cookie

 

五、Session

 

六、分頁

 

七、緩存

 

八、序列化

 

九、信號

 

參考:css

Web框架:http://www.cnblogs.com/wupeiqi/articles/5237672.html
Django【基礎篇】:http://www.cnblogs.com/wupeiqi/articles/5237704.html
Django【進階篇】:http://www.cnblogs.com/wupeiqi/articles/5246483.html
相關文章
相關標籤/搜索