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
相關文章
相關標籤/搜索