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()
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()
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>
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。
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要加環境變量
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 業務代碼
""" 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
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', ], }, }, ]
static --> 靜態文件目錄名字使用static STATICFILES_DIRS = ( os.path.join(BASE_DIR, 'static'), ) <link rel="stylesheet" href="/static/commons.css" />
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', ]
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), } }
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()
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 ]
from django.conf.urls import url urlpatterns = [ url(r'^index/', views.index), #一個url對應函數 url(r'^home/', views.Home.as_view()), #一個url對應類,根據method經過反射來執行對應方法 ]
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')
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)
<!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>
#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), ]
<!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>
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'
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 # 。。。
request.GET.get() request.POST.get() request.FILES.get() PS: GET:http請求默認使用的method,獲取數據 POST:能夠與GET區分,用來提交數據
request.POST.getlist()
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/')
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:類的方法名必定要小寫,源代碼中定義好了方法名 ====》 建議:二者都用
變量: {{ 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>
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>
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)
字符串******** 不一樣的字符串類型,只是給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/
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)
根據類對數據庫表中的數據進行各類操做 一對多: 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
參考:css