Django 02
復習:
Django下載:
在命令行輸入:
pip3 install django==1.11.11
在這里不要用最新的3.7,推薦使用3.6/3.5/3.4
判斷下載成功:
django-admin
創建django項目:
django-admin startproject 項目名
會創建跟項目同名的文件夾
settings.py 暴露給用戶可配置的配置文件
urls.py 路由與視圖函數對應文件
wsgi.py 就是封裝了socket與http協議的wsgiref模塊
manage.py django 的入口文件
創建app應用 (app就相當於大學里的學院,不同的學院有不同的功能)
第一種方法:
django-admin startapp app01
django-admin startapp 應用名
第二中方法:
python3 manage.py startapp 應用名
python3 manage.py startapp app01
app名文件夾下:
migrations文件夾 數據庫操作記錄
apps.py 注冊app相關文件
admin.py django后台管理相關
models.py orm 模型類相關
views.py 視圖函數(函數/ 類)
tests.py 測試相關
啟動django項目
python3 manage.py runserver django 默認是在8000 端口啟動項目
注意:用命令行創建的項目沒有templates文件夾
需要你自己手動在配置文件中添加該路徑,並且手動創建該文件夾
創建app后,也要在settings文件中注冊
django小白必會三板斧
HttpResponse 返回字符串
render 返回html頁面
redirect 重定向
今日內容:
1,以登錄功能為例
靜態文件配置
form表單提交數據后如何獲取
request方法
pycharm連接數據庫與django使用mysql數據庫
django orm簡介
表字段的增刪改查
表數據的增刪改查
一:靜態文件配置:
1,首先創建app,去settings配置文件中進行注冊
2,html文件默認全部放在templates文件夾下
操作:
首相創建項目(在pycharm中)
1,點擊file=》new Project =》Django
2,創建app應用
在命令行輸入:python manage.py startapp app01(tab鍵自動補全單詞)
3,應用創建成功:讓后去settings.py文件中進行注冊
新新創建的app一定要先去settings.py注冊
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
# 'app01' # 簡寫
'app01.apps.App01Config' # 全稱
]
4,views里面放的是功能,即不同的學院有不同的功能,不同的功能用不同的應用
Django項目就是一個大學,大學里有不同的學院,所以要到urls,以及app應用下的views中建立關系
1,首先在urls文件中引入視圖函數
from app01 import views 導入views
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^login/', views.login), #引入視圖函數
]
2,讓后去視圖函數文件views 中,寫login函數
def login(request): # 在這里request作用和env參數很相似,就是瀏覽器發送來的請求相關的數據
return render(request,'login.html') # render 返回一個html頁面,第一個參數還是request,第二個參數是模板文件HTML的文件名
# 模板文件都放在了templates文件夾中,所以在此文件夾中新建login.html文件
ps:所有的web框架 html文件默認都放在templates文件夾下
對於前段已近寫好了的文件 我們只是拿過來使用,那么這些文件都可以稱之為靜態文件
靜態文件可以是 :
bootstrap一類的前段框架,已經寫好了的
圖片
css
靜態文件默認都放在static文件夾下:
static文件夾中默認會創建的子文件夾
css文件夾 當前網站所有的樣式文件
js文件 當前網站所有的js文件
img文件 當前網站所有的圖片文件
其他(前端框架代碼 第三方插件代碼....)
3,手動創建static文件夾,注意文件夾名固定就是static,別亂寫(static就是定位的時候默認的,什么相對定位,固定定位等等)
在它下面把bootstrap-3.3.7-dist文件夾復制進來
此文件夾下包括一個css文件和一個js文件
在login.html文件中引入這兩個文件,注意前提是必須先引入jq文件,然后在引入css文件和js文件,如下:
<title>Title</title>
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
<link rel="stylesheet" href="../static/bootstrap-3.3.7-dist/css/bootstrap.min.css">
<script src="../static/bootstrap-3.3.7-dist/js/bootstrap.min.js"></script>
這時候在return render(request,'login.html')自動就會提示login.html
是因為在settings.py文件中加了os.path.join(BASE_DIR, 'templates')] 它會自動去搜索
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [
os.path.join(BASE_DIR, 'templates')] ....}
ps:啟動DJango項目的時候 一定要確保一個端口號只有一個django項目在占用
不然的話 會容易造成bug
重點: 用戶可以訪問的資源都在url中
只有url中開設相關資源你才能訪問到(********)
也就是說用戶要找的資源只有在url中開設了才能訪問到,
后端的資源一般都需要手動指定是否需要暴露給用戶
靜態文件配制:
STATIC_URL = '/static/'
#在這句話下面
# 手動將static文件夾中的所有資源暴露給用戶
# 因為你的css樣式和js都是在static中,暴露給用戶無關緊要
# 進行靜態文件配置
STATICFILES_DIRS = [
os.path.join(BASE_DIR,'static')
] # 這一句話就是你將static中的文件全部暴露給用戶了
此時前端路徑就要進行更改
<link rel="stylesheet" href="/static/bootstrap-3.3.7-dist/css/bootstrap.min.css">
<script src="/static/bootstrap-3.3.7-dist/js/bootstrap.min.js"></script>
即把前面的.. 給去除了(把兩個點給去除了),用戶要想訪問static文件夾中的資源,必須把路徑輸全就可訪問
此時你只要輸入static文件夾內具體文件的路徑就能夠訪問到
STATIC_URL = '/static/' #這個static 不是文件夾名字,而是接口前綴
只要你想訪問靜態文件中的資源 文件路徑就必須用static開頭
# 手動將static文件夾中所有的資源暴露給用戶
STATICFILES_DIRS = [
os.path.join(BASE_DIR,'static'), # 真正的文件夾路徑
os.path.join(BASE_DIR,'static1'), # 真正的文件夾路徑
os.path.join(BASE_DIR,'static2'), # 真正的文件夾路徑
os.path.join(BASE_DIR,'static3') # 真正的文件夾路徑
]
django默認是支持自動重啟代碼的 所以你只需要多刷新幾次頁面就可以
但是有時候它的重啟機制比較慢
機制:實時監測文件代碼變化 只要有變化 就會自動重啟
可能你的代碼還沒有寫完 這個時候就會自動報錯
瀏覽有緩存機制
要清楚緩存 在游覽器的檢查 network中。。。。
如果有1000個文件都要進行修改靜態文件夾的名稱那怎么辦?
無論怎么改。實現自動解析,在這里用解析器就能解決
靜態文件接口前綴"動態解析"
{% load static %}
<link rel="stylesheet" href="{% static 'bootstrap-3.3.7-dist/css/bootstrap.min.css' %}">
<script src="{% static 'bootstrap-3.3.7-dist/js/bootstrap.min.js' %}"></script>
無論怎么改。實現自動解析,在這里用解析器就能解決
靜態文件接口前綴"動態解析"
{% load static %}
<link rel="stylesheet" href="{% static 'bootstrap-3.3.7-dist/css/bootstrap.min.css' %}">
<script src="{% static 'bootstrap-3.3.7-dist/js/bootstrap.min.js' %}"></script>
最終格式:如上
2,form表單提交數據
form表單默認的是get請求,攜帶數據的方式是url?后面跟數據,這樣數據就直接暴露出來了
http://localhost:8000/login/?username=sss&password=111
此時要想不在url后面顯示,就要改為post請求
<form action="" method="post">
<p>username:<input type="text" name="username" class="form-control"></p>
<p>password:<input type="password" name="password" class="form-control"></p>
<input type="submit" class="btn btn-success">
</form>
可以通過method改為post請求
改成post請求之后 需要去settings文件中注釋掉一個中間件
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',
]
form表單提交數據目的地由action
1.不寫的情況下 默認往當前地址提交
2.還可以寫后綴/index/(將項目常用這種)
3.還可以寫全路徑
def login(request):
# 在沒指定提交方式的時候,那就是當前提交,post和get都會走這里
print('收到了')
# 視圖函數針對不同的請求方式,應該有不同的處理邏輯
# 所以要進行條件判斷,是get請求應該做什么,是post請求應該做什么
if request.method == 'GET':
print(request.method) # 能夠獲取前端請求方式 並且是全大寫的字符串
return render(request,'login.html')
elif request.method == 'POST':
# 獲取用戶輸入 做相應的邏輯判斷
return HttpResponse('來了,今夜好寂寞!')
可簡寫:
if request.method == 'POST':
return HttpResponse('來了,今夜好寂寞!')
return render(request, 'login.html')
獲取數據攜帶過來的參數,get請求也可攜帶參數,post請求也可攜帶參數
在這里以post請求攜帶參數為例:
基於網絡發過來的數據都是二進制數據
獲取前端數據
request.method獲取請求方法
對數據的處理 不單單只有wsgiref模塊 django后端也進行了大量的數據處理
GET
request.GET獲取前端get提交的數據(就類似於是一個大字典)
取值
request.GET.get('username') # 雖然value是一個列表 但是默認只取列表最后一個元素
# 強烈不建議你使用中括號的形式取值
# 如果想直接把列表全部取出(******)
request.GET.getlist('hobby')
POST
request.POST獲取前端post提交的數據(就類似於是一個大字典)
取值
request.POST.get('username') # 雖然value是一個列表 但是默認只取列表最后一個元素
# 強烈不建議你使用中括號的形式取值
# 如果想直接把列表全部取出(******)
request.POST.getlist('hobby')
具體例子:
if request.method == 'POST':
print(request.POST) # 獲取前端post請求提交過來的數據 就把它當成一個大字典即可
#<QueryDict: {'username': ['jason'], 'password': ['123']}>
# 若有相同的框,或者例如愛好可以有多個
# <QueryDict: {'username': ['zaikai', 'jason'], 'password': ['123']}>
username = request.POST.get('username') # 此時get默認取最后一個
password = request.POST.get('password')
#hobby = request.POST.get('hobby')
# <QueryDict: {'username': ['jason', 'zaikai'],
# 'password': ['123'], 'hobby': ['basketball',
# 'lianqiu', 'football']}>
# print(username,password,hobby) #zaikai 123 football
# 此時get取值取的是最后一個,要取出所有數據時,用getlist
hobby = request.POST.getlist('hobby')
print(username,password,hobby)
print(type(username),type(password),type(hobby)) #<class 'str'> <class 'str'> <class 'list'>
#rrr 123 ['basketball', 'lianqiu', 'football']
# 此時getlist取出來就是所有的
3,django連接數據庫:
django默認使用自帶的sqlite數據庫
如果要使用其他數據庫 需要在settings配置文件中進行配置
1.settings文件中配置
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'day51',
'HOST':'127.0.0.1',
'PORT':3306,
'USER':'root',
'PASSWORD':'123',
'CHARSET':'utf8'
} #在配置的時候 鍵必須全大寫
2.還要在項目名下的init文件或者是應用名下的init文件中告訴django不要使用默認的mysqldb連接mysql
而是使用pymysql
import pymysql
pymysql.install_as_MySQLdb()
2,form表單提交數據
form表單默認的是get請求,攜帶數據的方式是url?后面跟數據,這樣數據就直接暴露出來了
http://localhost:8000/login/?username=sss&password=111
此時要想不在url后面顯示,就要改為post請求
<form action="" method="post">
<p>username:<input type="text" name="username" class="form-control"></p>
<p>password:<input type="password" name="password" class="form-control"></p>
<input type="submit" class="btn btn-success">
</form>
可以通過method改為post請求
改成post請求之后 需要去settings文件中注釋掉一個中間件
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',
]
form表單提交數據目的地由action
1.不寫的情況下 默認往當前地址提交
2.還可以寫后綴/index/(將項目常用這種)
3.還可以寫全路徑
def login(request):
# 在沒指定提交方式的時候,那就是當前提交,post和get都會走這里
print('收到了')
# 視圖函數針對不同的請求方式,應該有不同的處理邏輯
# 所以要進行條件判斷,是get請求應該做什么,是post請求應該做什么
if request.method == 'GET':
print(request.method) # 能夠獲取前端請求方式 並且是全大寫的字符串
return render(request,'login.html')
elif request.method == 'POST':
# 獲取用戶輸入 做相應的邏輯判斷
return HttpResponse('來了,今夜好寂寞!')
可簡寫:
if request.method == 'POST':
return HttpResponse('來了,今夜好寂寞!')
return render(request, 'login.html')
獲取數據攜帶過來的參數,get請求也可攜帶參數,post請求也可攜帶參數
在這里以post請求攜帶參數為例:
基於網絡發過來的數據都是二進制數據
獲取前端數據
request.method獲取請求方法
對數據的處理 不單單只有wsgiref模塊 django后端也進行了大量的數據處理
GET
request.GET獲取前端get提交的數據(就類似於是一個大字典)
取值
request.GET.get('username') # 雖然value是一個列表 但是默認只取列表最后一個元素
# 強烈不建議你使用中括號的形式取值
# 如果想直接把列表全部取出(******)
request.GET.getlist('hobby')
POST
request.POST獲取前端post提交的數據(就類似於是一個大字典)
取值
request.POST.get('username') # 雖然value是一個列表 但是默認只取列表最后一個元素
# 強烈不建議你使用中括號的形式取值
# 如果想直接把列表全部取出(******)
request.POST.getlist('hobby')
具體例子:
if request.method == 'POST':
print(request.POST) # 獲取前端post請求提交過來的數據 就把它當成一個大字典即可
#<QueryDict: {'username': ['jason'], 'password': ['123']}>
# 若有相同的框,或者例如愛好可以有多個
# <QueryDict: {'username': ['zaikai', 'jason'], 'password': ['123']}>
username = request.POST.get('username') # 此時get默認取最后一個
password = request.POST.get('password')
#hobby = request.POST.get('hobby')
# <QueryDict: {'username': ['jason', 'zaikai'],
# 'password': ['123'], 'hobby': ['basketball',
# 'lianqiu', 'football']}>
# print(username,password,hobby) #zaikai 123 football
# 此時get取值取的是最后一個,要取出所有數據時,用getlist
hobby = request.POST.getlist('hobby')
print(username,password,hobby)
print(type(username),type(password),type(hobby)) #<class 'str'> <class 'str'> <class 'list'>
#rrr 123 ['basketball', 'lianqiu', 'football']
# 此時getlist取出來就是所有的
3,django連接數據庫:
django默認使用自帶的sqlite數據庫
如果要使用其他數據庫 需要在settings配置文件中進行配置
1.settings文件中配置
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'day51',
'HOST':'127.0.0.1',
'PORT':3306,
'USER':'root',
'PASSWORD':'123',
'CHARSET':'utf8'
} #在配置的時候 鍵必須全大寫
2.還要在項目名下的init文件或者是應用名下的init文件中告訴django不要使用默認的mysqldb連接mysql
而是使用pymysql
import pymysql
pymysql.install_as_MySQLdb()
4,django orm簡介
orm對象關系映射
表 類
一條條記錄 對象
記錄中的字段 對象.屬性
首先需要在應用下的models.py中書寫模型類
class User(models.Model):
# 將id字段設置為User表主鍵字段 在django orm中 你可以不寫主鍵字典 django會默認給你的表創建一個名為id的主鍵字段
# id = models.AutoField(primary_key=True) # 一旦你自己指定了主鍵字段 那么django就不會自動再幫你創建了
username = models.CharField(max_length=32) # username varchar(32) CharField必須要指定max_length參數
password = models.IntegerField() # password int
*************************需要執行數據庫遷移(同步)命令******************************
python3 manage.py makemigrations # 僅僅是在小本本上(migrations文件夾)記錄數據庫的修改 並不會直接操作數據
python3 manage.py migrate # 將數據庫修改記錄 真正同步到數據庫
注意:只要動了models中跟數據庫相關的代碼 就必須重新執行上面的兩條命令 缺一不可(******)
orm對象關系映射
表 類
一條條記錄 對象
記錄中的字段 對象.屬性
首先需要在應用下的models.py中書寫模型類
class User(models.Model):
# 將id字段設置為User表主鍵字段 在django orm中 你可以不寫主鍵字典 django會默認給你的表創建一個名為id的主鍵字段
# id = models.AutoField(primary_key=True) # 一旦你自己指定了主鍵字段 那么django就不會自動再幫你創建了
username = models.CharField(max_length=32) # username varchar(32) CharField必須要指定max_length參數
password = models.IntegerField() # password int
*************************需要執行數據庫遷移(同步)命令******************************
python3 manage.py makemigrations # 僅僅是在小本本上(migrations文件夾)記錄數據庫的修改 並不會直接操作數據
python3 manage.py migrate # 將數據庫修改記錄 真正同步到數據庫
注意:只要動了models中跟數據庫相關的代碼 就必須重新執行上面的兩條命令 缺一不可(******)
表字段的增刪改查
增
當一張表已經創建出來之后 后續還想添加字段,可以有兩種方式
1.給新增的字段設置默認值
addr = models.CharField(max_length=32,default='China') # default該字段默認值
增
當一張表已經創建出來之后 后續還想添加字段,可以有兩種方式
1.給新增的字段設置默認值
addr = models.CharField(max_length=32,default='China') # default該字段默認值
2.給新增的字段設置成可以為空
age = models.IntegerField(null=True) # 該字段允許為空
刪(慎用)
刪除字段 直接在models.py中注釋該字段 然后重新執行兩條命令即可
注意:執行完之后 表中該字段所對應的所有的數據全部刪除
並且一般情況下 基本是不會用到真正意義上的刪除
age = models.IntegerField(null=True) # 該字段允許為空
刪(慎用)
刪除字段 直接在models.py中注釋該字段 然后重新執行兩條命令即可
注意:執行完之后 表中該字段所對應的所有的數據全部刪除
並且一般情況下 基本是不會用到真正意義上的刪除
orm操作需要使用models中的類的名字
數據的查
from app01 import models
models.User.objects.all() # 直接拿所有的數據
models.User.objects.get(username=username)
res = models.User.objects.filter(username=username)
res.query
user_obj = res.first()
數據的增
1.
models.User.objects.create(username=username,password=password)
2.
user_obj = models.User(username=username,password=password)
user_obj.save()
from app01 import models
models.User.objects.all() # 直接拿所有的數據
models.User.objects.get(username=username)
res = models.User.objects.filter(username=username)
res.query
user_obj = res.first()
數據的增
1.
models.User.objects.create(username=username,password=password)
2.
user_obj = models.User(username=username,password=password)
user_obj.save()
刪
models.User.objects.filter(條件).delete()
models.User.objects.filter(條件).delete()
改
models.User.objects.filter(條件).update()
用戶的增刪改查
1.通過orm展示所有的到前端
all()
模板語法for循環
2.添加新增按鈕 (用戶的新增操作)
a標簽的href直接觸發后端邏輯
create()
3.添加編輯 刪除按鈕
編輯
刪除
利用get請求攜帶參數的特點 在url的后面跟上對應數據的id值
request.GET.get()
如果是編輯
重新渲染一個頁面 將編輯對象傳遞到前端
如果是刪除
直接利用filter(...).delete()
models.User.objects.filter(條件).update()
用戶的增刪改查
1.通過orm展示所有的到前端
all()
模板語法for循環
2.添加新增按鈕 (用戶的新增操作)
a標簽的href直接觸發后端邏輯
create()
3.添加編輯 刪除按鈕
編輯
刪除
利用get請求攜帶參數的特點 在url的后面跟上對應數據的id值
request.GET.get()
如果是編輯
重新渲染一個頁面 將編輯對象傳遞到前端
如果是刪除
直接利用filter(...).delete()