目錄css
MVC百度百科:全名Model View Controller,是模型(model)-視圖(view)-控制器(controller)的縮寫,一種軟件設計典範,用一種業務邏輯、數據、界面顯示分離的方法組織代碼,將業務邏輯彙集到一個部件裏面,在改進和個性化定製界面及用戶交互的同時,不須要從新編寫業務邏輯。html
通俗解釋:一種文件的組織和管理形式!不要被縮寫嚇到了,這其實就是把不一樣類型的文件放到不一樣的目錄下的一種方法,而後取了個高大上的名字。固然,它帶來的好處有不少,好比先後端分離,鬆耦合等等。前端
MTV: 有些WEB框架以爲MVC的字面意思很彆扭,就給它改了一下。view再也不是HTML相關,而是主業務邏輯了,至關於控制器。html被放在Templates中,稱做模板,因而MVC就變成了MTV。這其實就是一個文字遊戲,和MVC本質上是同樣的,換了個名字和叫法而已,換湯不換藥。python
Django的MTV模式本質上和MVC是同樣的,也是爲了各組件間保持鬆耦合關係,只是定義上有些許不一樣,Django的MTV分別是指:mysql
M 表明模型(Model): 負責業務對象和數據庫的關係映射(ORM)。 T 表明模板 (Template):負責如何把頁面展現給用戶(html)。 V 表明視圖(View): 負責業務邏輯,並在適當時候調用Model和Template。
除了以上三層以外,還須要一個URL分發器,它的做用是將一個個URL的頁面請求分發給不一樣的View處理,View再調用相應的Model和Template,MTV的響應模式以下所示:jquery
用戶經過瀏覽器向咱們的服務器發起一個請求(request),這個請求會去訪問視圖函數,(若是不涉及到數據調用,那麼這個時候視圖函數返回一個模板也就是一個網頁給用戶),視圖函數調用模型,模型去數據庫查找數據,而後逐級返回,視圖函數把返回的數據填充到模板中,最後返回網頁給用戶。web
python3.五、pip3及pycharm專業版可自行安裝。
例:windows cmd命令行自動安裝Pypi提供的最新版本。
pip3 install django
正則表達式
成功安裝Djangio後,若有須要,能夠將python的Scripts目錄加入到系統環境變量中,以便調用django-admin命令。sql
配置完成後,可直接在cmd任一路徑下運行django-admin help命令測試安裝和配置完成:
數據庫
django-admin startproject mysite
python manage.py startapp blog
python manage.py runserver 8080
通常開發使用pycharm(IDE)操做是點擊file-new project,選擇Django欄目;
右側選擇項目所在路徑,選擇項目使用的python版本環境(可選虛擬環境),
注意Location中選擇項目路徑的同時所選的目錄也就是項目的名稱,
More Settings欄可設置模板文件夾名,web應用名稱,勾選自動建立相關web應用文件夾等。
點擊右下方的Create按鈕建立。
Django自動生成相似下面的目錄結構:
推薦在項目根目錄下自行創建起一個static的靜態文件,用於存放css,js,img,html等靜態文件。
路由由urls文件進行處理,功能是將瀏覽器輸入的url映射到相應的(views)業務處理邏輯。
因爲和業務處理邏輯相關,也就是和views相關,因此在文件開頭就須要先導入對應app的views.py文件。
例:沒作增添以前的urls.py(包括了官方註釋)
"""tielemao URL Configuration The `urlpatterns` list routes URLs to views. For more information please see: https://docs.djangoproject.com/en/2.0/topics/http/urls/ Examples: Function views 1. Add an import: from my_app import views 2. Add a URL to urlpatterns: path('', views.home, name='home') Class-based views 1. Add an import: from other_app.views import Home 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home') Including another URLconf 1. Import the include() function: from django.urls import include, path 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) """ from django.contrib import admin from django.urls import path urlpatterns = [ path('admin/', admin.site.urls), ]
增添路由條目後:
from django.contrib import admin from django.urls import path # 需先導入對應的app目錄中的views文件 from app01 import views urlpatterns = [ # admin爲後臺管理的路由,通常不會暴露出來,註釋掉居多 # path('admin/', admin.site.urls), # 本身新增的路由條目,前半部分表示路徑的爲正則表達式,後半部分爲對應的業務邏輯函數 path('index/', views.index), ]
urls.py中增添的路由條目中對應了相應的本身命名的業務邏輯函數,
也就是接下來你就須要爲此在相應的views.py文件增添上相應的視圖函數。
原始的views.py文件:
from django.shortcuts import render # Create your views here.
增添相應函數後:
from django.shortcuts import render # 導入HttpResponse模塊 from django.shortcuts import HttpResponse # Create your views here. # request參數按規範必須有,相似self的默認存在,名字能夠改,但不建議。 # 它裏面封裝了用戶請求的全部內容。 def index(request): # 能夠print打印request.POST或request.GET來查看到請求 # print(request.POST) # print(request.GET) # 正常是不能直接返回字符串,必須使用Django提供的HttpResponse # 這個類封裝起來就能夠返回字符串了,這是Django的規則,不是python的。 return HttpResponse("hello world!")
經過上面兩個簡單的步驟,將index這個url指向了views裏的index()函數,它接收用戶請求,並返回一個「hello world」字符串。
咱們就能夠啓動web服務演示一下了。
python manage.py runserver 127.0.0.1:8000
運行效果:
在瀏覽器中訪問http://127.0.0.1:8000
此時會出現404的錯誤信息,由於此時咱們訪問的地址並非index/,在開發過程當中,Django給出的這些錯誤信息很重要,仔細閱讀方便排錯,但一旦正式上線生產環境,就必定要關掉如此詳細的調錯信息功能,常見的錯誤就本身另寫html報錯頁面。
在地址欄中輸入http://127.0.0.1:8000/index/,訪問纔會出現己設置好的正常顯示的hello world!
上面例子返回給用戶的是一個字符串,真正的web應用確定是不會這樣作的,一般返回的都應該是一個HTML文件給用戶。那麼,咱們寫以下showtime函數和time.html的HTML文件,作爲一個用戶訪問獲取
當前時間的功能例子:
from django.contrib import admin from django.urls import path # 需先導入對應的app目錄中的views文件 from app01 import views urlpatterns = [ # admin爲後臺管理的路由,通常不會暴露出來,註釋掉居多 path('admin/', admin.site.urls), # 本身新增的路由條目,前半部分表示路徑的爲正則表達式,後半部分爲對應的業務邏輯函數 path('index/', views.index), # 新增用戶訪問time/路由,獲取當前時間函數 path('time/', views.showtime), ]
from django.shortcuts import render # 導入HttpResponse模塊 from django.shortcuts import HttpResponse # 導入時間模塊 import datetime # Create your views here. # request參數按規範必須有,相似self的默認存在,名字能夠改,但不建議。 # 它裏面封裝了用戶請求的全部內容。 def index(request): # 正常是不能直接返回字符串,必須使用Django提供的HttpResponse # 這個類封裝起來就能夠返回字符串了,這是Django的規則,不是python的。 return HttpResponse("hello world!") def showtime(request): now=datetime.datetime.now() ctime=now.strftime("%Y-%m-%d %X") return render(request, "time.html", {"ctime":ctime})
request,它是一個對象。
當中存儲了請求信息,好比請求路徑,請求方式,GET數據,POST數據...等等。
必需要接收一個request參數。
當你想返回一個html文件時,不是使用HttpResponse方法,而是使用render方法來渲染(打包)。
不過本質上render最終仍是使用了HttpResponse方法發送byte字節給瀏覽器的。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> {# 由兩個大括號括起來裏面加個變量名,至關因而字典的鍵名,是django用於佔位輸出的語法 #} <h3>當前時間:{{ ctime }}</h3> </body> </html>
訪問效果以下:
settings.py文件中有TEMPLATES變量,它是一個列表,列表中又存放了一個字典,其中一個鍵值對
'DIRS':[os.path.join(BASE_DIR, 'templates')]
效果就是默認設置了模板目錄是使用默認的項目文件夾下的templates目錄。
若是有特殊須要修改的就是在此改動。
另外django有一個好處,代碼更改以後,通常無需重啓web服務,它會自動加載最新代碼。
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', ], }, }, ]
將html文件返回給用戶還不夠,前端三大塊,HTML、CSS、JS還有各類插件等,完整齊全才是一個好看的頁面。在django中,通常將靜態文件放在static目錄中。接下來,在項目根目錄下新建一個static目錄。
同時,我還在此目錄下創建起js,css,img子目錄和相關文件,如圖:
static這個靜態目錄名和Django默認設置的靜態目錄名別名一致,
在settings.py中可找到相關設置項,就是在結尾處再添加上新的一行表示告訴Django靜態目錄的路徑:
# Static files (CSS, JavaScript, Images) # https://docs.djangoproject.com/en/2.0/howto/static-files/ STATIC_URL = '/static/' # STATIC_URL表示的是引用別名(指針),不是具體的目錄 # 能夠改爲你想指定的名字,可是在相應的引用地方必須和它對應到 # 增長如下一段表示設置靜態目錄的路徑 STATICFILES_DIRS = ( os.path.join(BASE_DIR, 'static'), ) # 真實目錄名不要在html中寫死,而是寫成別名引用, # 如此,目錄名就算有改動也只需改動此處便可。 # 另外,因爲此行是一個元組,別忘了後面還需加個逗號。
同理,在html文件中引用靜態文件,例如jquery.js文件以下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> {# 由兩個大括號括起來裏面加個變量名,至關因而字典的鍵名,是django用於佔位輸出的語法 #} <h3>當前時間:{{ ctime }}</h3> <script src="/static/js/jquery.js"></script> </body> </html>
主要看<script src="/static/js/jquery.js"></script>
這一行,裏面的路徑並無寫死,而是使用了static/
來代指了真實的靜態目錄。
至此,咱們作到了將一個要素齊全的HTML文件返還給了用戶瀏覽器。
但這還不夠,由於web服務器和用戶之間尚未動態交互。
下面咱們來設計一個login頁面,上面創建一個表單,讓用戶輸入用戶名和密碼,提交給login
這個url,服務器將接收到這些數據。
login.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>登陸</title> </head> <body> <form action="" method="post"> {# 注意Django中有一個跨站請求保護機制,因此須要加如下一行 #} {% csrf_token %} 用戶名:<input type="text" name="user" /> 密碼:<input type="password" name="pwd" /> <input type="submit" value="提交" /> </form> </body> </html>
假如沒有加{% csrf_token %}
這一行防禦,運行時將會報以下圖的錯誤:
urls.py中urlpatterns
添加路由條目:
path('login/', views.login),
def login(request): if request.method=="POST": username = request.POST.get("user", None) password = request.POST.get("pwd", None) print("用戶名:", username,"密碼", password) return render(request, "login.html")
此邏輯處理將會在pycharm中能夠看到用戶輸入的用戶名密碼。
運行效果以下:
html頁面效果:
pycharm後端效果:
pycharm中能夠看到提交後的post請求數據後端都獲取到了。
咱們收到了用戶的數據,但返回給用戶的依然是個靜態頁面,一般頁面會根據用戶的數據,進行處理後在返回給用戶。
django採用本身的模板語言,相似jinja2,可根據提供的數據,替換掉HTML中的相應部分。
例:views.py文件修改以下:
# 建立一個用戶信息表,預設了兩個數據,將返回給瀏覽器展現給用戶 user_list = [ {"user":"tielemao", "pwd":"12345"}, {"user":"LiLei", "pwd":"abc123"}, ] def login(request): if request.method=="POST": username = request.POST.get("user", None) password = request.POST.get("pwd", None) temp = {"user":username, "pwd":password} user_list.append(temp) return render(request, "login.html", {"data":user_list}) # render接收的第三個參數是後臺返回給瀏覽器的數據,一個字典。 # data是字典的鍵,是你在login.html中自定義的指針名字,對應引用值。
而login.html相應修改:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>登陸</title> </head> <body> <form action="" method="post"> {# 注意Django中有一個跨站請求保護機制,因此須要加如下一行 #} {% csrf_token %} 用戶名:<input type="text" name="user" /> 密碼:<input type="password" name="pwd" /> <input type="submit" value="提交" /> </form> <h2>用戶列表</h2> <table border="1"> <thead> <th>用戶名</th> <th>密碼</th> </thead> <tbody> {% for line in data %} <tr> <td>{{ line.user }}</td> <td>{{ line.pwd }}</td> </tr> {% endfor %} </tbody> </table> </body> </html>
login.html中利用for循環將data(引用)迭代填入數據到表格。
訪問頁面並輸入一些數據測試效果以下:
效果就是用戶列表會隨着提交的數據而發生變化,算是一個簡單的動態頁面, 和用戶的交戶過程。
上面咱們雖然和用戶交互得很好,但並無保存任何數據,頁面一旦關閉,或服務器重啓,一切都將回到原始狀態。
使用數據庫是正常最多見的,django經過自帶的ORM框架操做數據庫,而且自帶輕量級的sqlite3數據庫。此次咱們先來使用sqlite數據庫來演示,後面再學習詳細使用mysql。
首先是註冊app,不進行這一步的話django不會知道該給哪一個app建立表。
# Application definition INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'app01.apps.App01Config', ]
例,由於我以前執行了建立應用的命令,django2.06版本自動在建立應用的同時就幫我註冊了app,就是上面代碼中的app01.apps.App01Config
。若是重複註冊一個app01,會在運行python manage.py makemigrationsw
命令的時候報錯django.core.exceptions.ImproperlyConfigured: Application labels aren't unique, duplicates: app01
而後在settings中,配置數據庫相關的參數,此次使用自帶的sqlite,不須要修改。
# Database # https://docs.djangoproject.com/en/2.0/ref/settings/#databases DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), } }
from django.db import models # Create your models here. # 固定繼承models.Model這個類 class UserInfo(models.Model): id = models.AutoField(primary_key=True) user = models.CharField(max_length=32) pwd = models.CharField(max_length=32)
以上建立了三個字段,分別保存id,用戶名和密碼。
python manage.py makemigrations
Create model UserInfo
```
python manage.py migrate
E:\Django\tielemao>python manage.py migrate Operations to perform: Apply all migrations: admin, app01, auth, contenttypes, sessions Running migrations: Applying contenttypes.0001_initial... OK Applying auth.0001_initial... OK Applying admin.0001_initial... OK Applying admin.0002_logentry_remove_auto_add... OK Applying app01.0001_initial... OK Applying contenttypes.0002_remove_content_type_name... OK Applying auth.0002_alter_permission_name_max_length... OK Applying auth.0003_alter_user_email_max_length... OK Applying auth.0004_alter_user_username_opts... OK Applying auth.0005_alter_user_last_login_null... OK Applying auth.0006_require_contenttypes_0002... OK Applying auth.0007_alter_validators_add_error_messages... OK Applying auth.0008_alter_user_username_max_length... OK Applying auth.0009_alter_user_last_name_max_length... OK Applying sessions.0001_initial... OK
db.sqlite3
文件
from django.shortcuts import render # 導入models文件 from app01 import models def login(request): if request.method=="POST": username = request.POST.get("user", None) password = request.POST.get("pwd", None) # 添加數據到數據庫 models.UserInfo.objects.create(user=username, pwd=password) # 從數據庫中讀取全部數據 user_list = models.UserInfo.objects.all() return render(request, "login.html", {"data":user_list}) # render接收的第三個參數是後臺返回給瀏覽器的數據,一個字典。 # data是字典的鍵,是你在login.html中自定義的指針名字,對應引用值。
重啓web服務,刷新瀏覽器頁面,以後和用戶交互的數據都能保存到數據庫中。
任什麼時候候均可以從數據庫中讀取數據,展現到頁面上。
至此,一個要素齊全,主體框架展現清晰的簡單django項目完成了。
【end】