Django 复习
?
?Django 基礎1
day49
老師的博客:
https://www.cnblogs.com/yuanchenqi/articles/6083427.html
http://www.cnblogs.com/haiyan123/p/7701412.html
MVC和MTV模型:
著名的MVC模式:所謂MVC就是把web應用分為模型(M),控制器(C),視圖(V,html文件)三層;他們之間以一種插件似的,松耦合的方式連接在一起。
模型負責業務對象與數據庫的對象(ORM),視圖負責與用戶的交互(頁面),控制器(C)接受用戶的輸入調用模型和視圖完成用戶的請求。
???????????????????
Django的MTV模式本質上與MVC模式沒有什么差別,也是各組件之間為了保持松耦合關系,只是定義上有些許不同,Django的MTV分別代表:
? ? ? ?Model(模型):負責業務對象與數據庫的對象(ORM)
? ? ? ?Template(模版,html文件):負責如何把頁面展示給用戶
? ? ? ?View(視圖):負責業務邏輯,并在適當的時候調用Model和Template
? ? ? ?此外,Django還有一個url分發器,它的作用是將一個個URL的頁面請求分發給不同的view處理,view再調用相應的Model和Template
Django 的流程和命令行工具
安裝django
pip3 install django---->添加環境變量
創建項目(工程)
django-admin startproject p2p
---p2p(下面的文件是全局的)
---settings.py 配置
---urls.py 路由分發
---wsgi.py web
---manage.py
創建應用(App),我們的app01 的應用寫在這里
python? manage.py startapp app01
我們創建了一個app01 后,我們要到全局配置p2p/settings.py 里??INSTALLED_APPS 添加一行 “app01”
?
現在我們給app01 這個應用添加一個show_time 的功能,因為我們的所有的邏輯是寫在views里,所以我們在app01/views.py 里定義如下函數
def show_time():
pass
然后我們在全局路由urls.py里配置路由轉發規則
from app01 import views path('show_time/', views.show_time)django2 這里是urls(r'show_time/', views.show_time)
django3 這里是path
因為我們返回的是字符串給瀏覽器,所以這里我們引入HttpResponse from django.shortcuts import render,HttpResponse
def show_time(request):
return HttpResponse("hello") 我們把所有的靜態文件放在template 目錄下,這里我們修改一下settings.py
注釋掉 # TEMPLATE_DIRS = (os.path.join(BASE_DIR,'templates'),)
在 TEMPLATES 列表里的字典 DIRS=[] 改成 'DIRS': [os.path.join(BASE_DIR,'templates')]
我們的views.py 這么寫 from django.shortcuts import render,HttpResponse import time # Create your views here.def show_time(request):# return HttpResponse("hello world")local_time=time.ctime()return render(request,"index.html",{"time":local_time}) 這里的 {"time":local_time} 渲染給前端。前端通過{{ time }}來接收參數 templates 下的index.html 這么寫。這里兩個大括號的作用就是渲染 time 變量 <!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>Title</title> </head> <body><h1>hello bigbao {{ time }}</h1> </body> </html>
這里我們用前面學到的jquery知識,我們把前端展示的字體變成紅色(錯誤示范)
1、我們把jqeuery-3.1.1.js文件放到templates目錄下
2、index.html 做如下調整
<h1>hello bigbao {{ time }}</h1> <script src="jquery-3.1.1.js"></script><script>$("h1").css("color","red") </script>3、我們再去訪問一下,看到字體顏色沒有變化,報如下的錯誤
這里錯誤的原因是Django沒有找到這個jquery文件
這里我們應該在項目里面創建一個static目錄(和應用同級),這個我們后面放js,css,img
然后我們把jquery文件放在staic目錄下,然后我們在settings.py 里進行配置,讓Django知道靜態文件放在哪里了
STATIC_URL = '/static/'STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static'),]
這里必須用?STATICFILES_DIRS 這個名字,同時別忘了 逗號
?這里說一個問題,我一開始試驗的時候,我這里創建的目錄的名字是statics ,然后我這里配置的是
STATIC_URL = '/static/'STATICFILES_DIRS = [os.path.join(BASE_DIR, 'statics'),]但是訪問的時候還是404,我這里用上面那種方法就是可以用的。現在我們解釋一下
STATIC_URL 和 STATICFILES_DIRS STATICFILES_DIRS 是告訴Django 的static的絕對路徑,但是引用的時候用的是STATIC_URL# STATIC_URL 是別名,以后實際用的時候用的是這個別名,STATICFILES_DIRS 是Django用的,STATICFILES_DIRS 和 STATIC_URL 必須都存在,結合使用的
# 我們在用STATIC_URL別名的時候,Django 會自己去找到他的實際路徑,我們在html應用靜態文件的時候必須用別名,比如
# <script src="/static/jquery.js"></script>
# 文件的實際存在目錄,必須叫STATICFILES_DIRS
?所以我們index.html 用下面的方式就可以改變頁面的字體顏色了
<h1>hello bigbao {{ time }}</h1> <script src="/static/jquery-3.1.1.js"></script> 這里的static用的是配置文件的別名<script>$("h1").css("color","red") </script> 再說一下上面的問題,假如說我們的靜態文件的真實路徑的名字是 bigbao_static 那么這里我們的settings.py配置是這樣的 ------------------------------------------------------------------------------------------- STATIC_URL = '/static/'STATICFILES_DIRS = [os.path.join(BASE_DIR, 'bigbao_static'),]------------------------------------------------------------------------------------------- html 文件是這樣的 <h1>hello bigbao {{ time }}</h1> <script src="/static/jquery-3.1.1.js"></script><script>$("h1").css("color","red") </script>因為這里我們的別名是static,記住這句話 STATIC_URL 和 STATICFILES_DIRS 是想呼應的,STATICFILES_DIRS 是給Django用的,他去找真實的路徑,STATIC_URL別名是給后面項目實際調用的 所以我們在html文件里要是寫真實的靜態文件路徑是不行的<script src="/bigbao_static/jquery-3.1.1.js"></script>還有一種方案就是load,后面推薦使用的,但是我們剛剛前面配置的STATIC_URL 和 STATICFILES_DIRS不能注釋掉,我們在html文件里這么寫
?
<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"> {% load staticfiles %} <title>Title</title> </head> <body><h1>hello bigbao {{ time }}</h1> {#<script src="/static/jquery-3.1.1.js"></script>#} {% static "jquery-3.1.1.js" %} <script>$("h1").css("color","red") </script></body> </html>其實在實際工作中我們應該把每個app的靜態文件放在自己應用的目錄下面,所以這里我們在自己的應用目錄下面app01創建一個static目錄
然后配置settings.py? ?STATICFILES_DIRS=[os.path.join(BASE_DIR,"app01","static")]
Django的URL控制系統
URL 的無名分組和有名分組
from app02 import views from django.conf.urls import urlurlpatterns = [ #無名分組 url(r'^article/\d{4}', views.year) ,url(r'^article/(\d{4})$', views.year2),如果有多個匹配一樣的時候,誰放在上面就匹配誰,上面的就會把下面的覆蓋了正則加上括號,就是分組,會把分組的內容作為year2函數的參數傳進去url(r'^article/(\d{4})/(\d{2})$', views.year_month), # 有名分組(就是給分組起個名字,這樣定義的好處就是按照關鍵字參數去傳參了,指名道姓的方式)url(r'^article/(?P<year>\d{4})/(?P<month>\d{2})$', views.year_month_hasname)
?捕獲的值作為關鍵字參數而不是位置參數傳遞給視圖函數。例如:
/articles/2005/03/ 請求將調用views.month_archive(request, year='2005', month='03')函數
這里我們也一個簡單的注冊頁面;
urls.pypath('register/', views.register,name="reg"), 這里的name 是一個別名,后面用這個別名 ----------------------------------------------------------------------------------------------------------------------------------views.py-------------------------------------------def register(request,*args,**kwargs):if request.method == "POST":# print(request.POST.get('username'))print(request.POST)return HttpResponse("Success")return render(request,"register.html") ----------------------------------------------------------------------------------------------------------------------------------register.html-------------------------------------- <!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>Title</title><style>*{padding: 0;margin: 0;}h1{text-align: center;}</style> </head><body> <h1>注冊系統</h1><form action="{% url 'reg' %}" method="post"> {#<form action="/register" method="get">#} {# 這倆action 路徑寫死了,這個時候我們應該在 urlpattern 上家一個別名#}<p>姓名<input type="text" name="username"></p><p>年齡<input type="text" name="age"></p><p>愛好<input type="checkbox" name="hobby" value="1">籃球<input type="checkbox" name="hobby" value="2">網球<input type="checkbox" name="hobby" value="3">足球</p><p><input type="submit" value="提交數據"></p> </form></body> </html>?
實際環境中我們應該根據應用來分發URL,所以這里我們應該用URLConf
操作方式是:
我們在項目下的主路由urls.py做如下修改
from django.urls import path 改成 from django.urls import path,include path('app01/', include('app01.urls')) 所有已app01 開頭的都跳到app01.urls路由?然后我們到app01 下創建urls.py文件
from django.urls import pathfrom app01 import views
urlpatterns = [
path('register/', views.register,name="reg"),
]
這個時候我們就不能用剛的方式去訪問了http://127.0.0.1:8000/register/這樣是訪問不到的
我們得用這種方式 http://127.0.0.1:8000/app01/register/
view(視圖)和template(模板)day50
http請求產生兩個核心對象
httpRequest
httpResponse
HTTPRequest的屬性和方法: # path: 請求頁面的全路徑,不包括域名 # # method: 請求中使用的HTTP方法的字符串表示。全大寫表示。例如 # # if req.method=="GET": # # do_something() # # elseif req.method=="POST": # # do_something_else() # # GET: 包含所有HTTP GET參數的類字典對象 # # POST: 包含所有HTTP POST參數的類字典對象 # # 服務器收到空的POST請求的情況也是可能發生的,也就是說,表單form通過 # HTTP POST方法提交請求,但是表單中可能沒有數據,因此不能使用 # if req.POST來判斷是否使用了HTTP POST 方法;應該使用 if req.method=="POST" # # # # COOKIES: 包含所有cookies的標準Python字典對象;keys和values都是字符串。 # # FILES: 包含所有上傳文件的類字典對象;FILES中的每一個Key都是<input type="file" name="" />標簽中 name屬性的值,FILES中的每一個value同時也是一個標準的python字典對象,包含下面三個Keys: # # filename: 上傳文件名,用字符串表示 # content_type: 上傳文件的Content Type # content: 上傳文件的原始內容 # # # user: 是一個django.contrib.auth.models.User對象,代表當前登陸的用戶。如果訪問用戶當前 # 沒有登陸,user將被初始化為django.contrib.auth.models.AnonymousUser的實例。你 # 可以通過user的is_authenticated()方法來辨別用戶是否登陸: # if req.user.is_authenticated();只有激活Django中的AuthenticationMiddleware # 時該屬性才可用 # # session: 唯一可讀寫的屬性,代表當前會話的字典對象;自己有激活Django中的session支持時該屬性才可用。#方法 get_full_path(), 比如:http://127.0.0.1:8000/index33/?name=123 ,req.get_full_path()得到的結果就是/index33/?name=123 req.path:/index33 full_path 拿到的含有參數
HtppResponse 對象
HttpResponse類在django.http.HttpResponse
render 和 render_to_response 的區別是render_to_response的第一個參數不用寫request,效果都是頁面渲染
render(request,"register.html")
render_to_resonse("register.html")
這里推薦使用render
locals()--->局部變量? 將函數文件中的所有變量傳遞給模板,這里我們建議不要使用locals(函數中的變量名得和模板文件中的變量名一致,我們也可以在模板文件中直接調用局部變量request.method),最好是指定變量傳遞模板文件,比如說render(request,"register.html",{"time":t,"username":name})
redirect
redirect(“/login/”) 頁面跳轉,register.html---->return redirect("login")---->urlpattern---->view---->def login()---->login.html---->我們可以看到瀏覽器的URL地址也發生了變化,從register到login
template(模板)
1、模板的組成:
HTML代碼+python邏輯控制代碼
2、邏輯控制代碼的組成
2.1、變量(使用雙大括號來應用變量)
html引用格式:{{ var_name }}
?
深度查詢(萬能的句點號)
.索引? ? --->列表
.key? ? ?--->字典
變量的過濾器
語法格式: {{obj|filter:param}}# 1 add : 給變量加上相應的值## 2 addslashes : 給變量中的引號前加上斜線## 3 capfirst : 首字母大寫## 4 cut : 從字符串中移除指定的字符## 5 date : 格式化日期字符串## 6 default : 如果值是False,就替換成設置的默認值,否則就是用本來的值## 7 default_if_none: 如果值是None,就替換成設置的默認值,否則就使用本來的值#實例:#value1="aBcDe" {{ value1|upper }}<br> 字母全部大寫#value2=5 {{ value2|add:3 }}<br> 加3#value3='he llo wo r ld' {{ value3|cut:' ' }}<br> 去除指定字符串#import datetime #value4=datetime.datetime.now() {{ value4|date:'Y-m-d' }}<br> 時間格式化#value5=[] {{ value5|default:'bigbao' }}<br> 當取指定字符串的時候,沒有的情況下給他設置一個默認值#value6='<a href="#">跳轉</a>'{{ value6 }}{% autoescape off %}{{ value6 }} {% endautoescape %}{{ value6|safe }}<br>{{ value6|striptags }}#value7='1234' {{ value7|filesizeformat }}<br> {{ value7|first }}<br> {{ value7|length }}<br> {{ value7|slice:":-1" }}<br>#value8='http://www.baidu.com/?a=1&b=3' {{ value8|urlencode }}<br>value9='hello I am yuan' <h1>{{ name_list.4|default:'h e l l o ' |upper|cut:" " }}</h1>模板中if 和 for 循環:{% 標簽 %}
標簽的使用tag(使用大括號和百分號的組合來使用tag)
view ----------------------------------------------def query(request):name_list=['bigbao','z ho ng','xiaohu']d={'name':'bigbao','age':18,'hobby':'girl'}return render(request,"index.html",locals())------------------------- html,這里的if 可以嵌套if ------------------------- {% if d.age < 15 %}<h1> hello {{ d.name }}</h1> {% elif d.age == 20 %}<h1>hello {{ d.hobby }}</h1> {% else %}<h1>hello {{ d.age }}</h1> {% endif %} {% if %} 標簽接受and,or或者not來測試多個變量值或者否定一個給定的變量 {% if %} 標簽不允許同一標簽里同時出現and和or,否則邏輯容易產生歧義,例如下面的標簽是不合法的:{% if obj1 and obj2 or obj3 %} forloop.counter 就是一個計數器,循環的次數,從1開始,但是要是forloop.counter0 就是從0開始計數了{% for foo in name_list %} <h1>{{ forloop.counter }} : {{ foo }}</h1> {% endfor %}還有一些其他的標簽以及自定義標簽,看一下老師的博客
模板繼承(extend)
正常情況下,我們有一部分樣式是想保持不變的。這個時候各個頁面都要繼承這個基礎樣式,有特殊需求的可以在自己的頁面進行修改。比如說下面這個例子
----------------------------------url.py-----------------------------------------------path('backend/',views.backend),path('teacher/',views.teacher,name="teacher"),path('student/',views.student,name="student"), ---------------------------------views.py--------------------------------------------- def backend(request):return render(request,'backend.html')def teacher(request):teacher_list=['teacher_1','teacher_2','teacher_3']return render(request,'teacher.html',locals())def student(request):student_list=['student_A','student_B','student_C']return render(request,'student.html',{'student':student_list}) --------------------------base.html------------------------------------------------------ <!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"> <title>{% block style %}{% endblock %}</title><script src="/static/jquery-3.1.1.js"></script><style>* {margin: 0;padding: 0;}.nav{line-height: 40px;width: 100%;background-color: #2459a2;color: white;font-size: 20px;text-align: center;}.left{float: left;width:20%;min-height: 600px;overflow: auto;background-color: #ededed;}.manager{text-align: center;padding: 20px 0;margin: 15px 0;font-size: 18px;}a {text-decoration: none;}.content{float: left;width: 70%;min-height: 600px;text-align: center;}h3{color: red;font-size: 50px;}</style> </head> <body> <div class="outer"><div class="nav">標題</div><div class="left"><div class="teacher manager"><a href="/teacher/">老師管理</a></div><div class="student manager"><a href="/student/">學生管理</a></div><div class="course manager"><a href="">課程管理</a></div><div class="classes manager"><a href="">班級管理</a></div></div> <div class="content">{% block content %}{% endblock %}</div> </div></body> </html>-----------------------------------backend.html------------------------------------- {% extends "base.html" %}{% block content %}<h1> Welcome To BigBaoOps</h1> {% endblock %}---------------------------------teacher.html----------------------------------------{% extends "base.html" %}{% block style %}Teacher Page {% endblock %}{% block content %}{% for foo in teacher_list %}<h2>{{ foo }}</h2>{% endfor %} {% endblock %}---------------------------------teacher.html----------------------------------------- {% extends "base.html" %}{% block style %}Student Page {% endblock %}{% block content %}{% for foo in student %}<h3>{{ foo }}</h3>{% endfor %}{% endblock %}?
這里我們在base.html 上指定的標簽上添加一個block,比如這里我給了我的title和我的content分別設置了block
然后在我們的子模塊上的第一行永遠是
{% extends "base.html" %}?然后對自己的 block 做格式設置以及文字添加
注意:
<1>如果在模板中使用 {% extends %} ,必須保證其為模板中的第一個模板標記。 否則,模板繼承將不起作用。<2>一般來說,基礎模板中的 {% block %} 標簽越多越好。 記住,子模板不必定義父模板中所有的代碼塊,因此你可以用合理的缺省值對一些代碼塊進行填充,然后只對子模板所需的代碼塊進行(重)定義。 俗話說,鉤子越多越好。<3>如果發覺自己在多個模板之間拷貝代碼,你應該考慮將該代碼段放置到父模板的某個 {% block %} 中。如果你需要訪問父模板中的塊的內容,使用 {{ block.super }}這個標簽吧,這一個魔法變量將會表現出父模板中的內容。 如果只想在上級代碼塊基礎上添加內容,而不是全部重載,該變量就顯得非常有用了。<4>不允許在同一個模板中定義多個同名的 {% block %} 。 存在這樣的限制是因為block 標簽的工作方式是雙向的。也就是說,block 標簽不僅挖了一個要填的坑,也定義了在父模板中這個坑所填充的內容。如果模板中出現了兩個相同名稱的 {% block %} 標簽,父模板將無從得知要使用哪個塊的內容。include 擴展模塊
在講解了模板加載機制之后,我們再介紹一個利用該機制的內建模板標簽:?{%?include?%}?。該標簽允許在(模板中)包含其它的模板的內容。 標簽的參數是所要包含的模板名稱,
可以是一個變量,也可以是用單/雙引號硬編碼的字符串。 每當在多個模板中出現相同的代碼時,就應該考慮是否要使用?{%?include?%}?來減少重復。
比如說我們現在有一個test.html ,但是我們想在 student.html 里面加載test.html 的內容
那么我們就在student.html 做如下設置
{% load staticfiles %}
然后在你想要的位置引入test.html 的內容的地方做如下設置
{% include "test.html" %}
轉載于:https://www.cnblogs.com/smail-bao/p/9885054.html
總結
- 上一篇: 类的初始化
- 下一篇: SpringBootStarter种类