django 武沛齊老師-最後一篇隨筆
阿新 • • 發佈:2020-08-17
基礎
https://www.cnblogs.com/wupeiqi/articles/5237704.html
進階
https://www.cnblogs.com/wupeiqi/articles/5246483.html
安裝
pip install django==1.11.14 -i http://pypi.douban.com/simple/ --trusted-host pypi.douban.com
解除安裝
pip uninstall django
建立 django 專案
django-admin startproject 專案名
django-admin startproject victory
執行 django 專案
cd victory
python manage.py runserver
建立 app
python manage.py startapp app名稱
python manage.py startapp app01
urls 檔案
urlpatterns = [ ] 對應 url 對映的列表
urlpatterns = [
url(r'^網址名稱/', 包模組.函式名),
url(r'^網址名稱/', 函式名),
]
wsgi 一套規則,介面,建立 socket
產品上線不使用預設的 wsgi , 使用 uwsgi + nginx
manage.py 管理 django 程式
settings 配置檔案
app 註冊
app 名稱.apps.app 名稱Config 或 app 名稱
app01.apps.App01Config 或 app01
templates 模板註冊
'DIRS': [os.path.join(BASE_DIR, 'templates')],
配置靜態資料夾 static
建立 static 靜態資料夾
STATICFILES_DIRS = (
os.path.join(BASE_DIR,'static'),
)
設定中文
LANGUAGE_CODE = 'zh-hans'
設定時區
TIME_ZONE = 'Asia/Shanghai'
設定資料庫為 mysql (注:先安裝 mysqlclient, pip install mysqlclient)
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': '資料庫名稱',
'USER':'使用者名稱',
'PASSWORD':'密碼',
'HOST':'127.0.0.1',
'PORT':'3306'
}
}
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'app02',
'USER':'root',
'PASSWORD':'root',
'HOST':'127.0.0.1',
'PORT':'3306'
}
}
ORM 物件關係對映,建立資料庫表不需要使用select , insert 語句了
資料庫遷移
python manage.py makemigrations
python manage.py migrate
app 目錄
migrations 記錄做過哪些修改資料表結構的操作
__init__ 檔案,python3 可以刪除,python2 不可以刪除
python2 預設 不帶 __init__ 檔案為普通資料夾,匯入會報錯
admin 後臺管理
在 admin 中,匯入 app 的 models 檔案
from app01 import models
將 models 裡面的資料表進行註冊
admin.site.register(models.UserInfo)
admin.site.register(models.UserType)
兩張表內容如下
class UserType(models.Model):
name = models.CharField(max_length=32)
class UserInfo(models.Model):
username = models.CharField(max_length=32)
pwd = models.CharField(max_length=32)
email = models.CharField(max_length=32)
user_type = models.ForeignKey('UserType')
# 使用 '' 將類名包裹,進行建立外來鍵
建立超級使用者
python manage.py createsuperuser
示例:
使用者名稱 hany
密碼 hany12345.
超級使用者登入後,可以對資料表增加資料等操作
apps 配置當前 app
models ORM 操作,通過命令建立資料庫表結構
tests 單元測試
views 業務邏輯檔案,寫函式
偽裝資料庫
專案的 __init__ 檔案下
import pymysql
pymysql.install_as_MySQLdb()
生命週期
使用者傳送請求到路由系統,如果匹配成功,執行相對應的 views 中的函式
到資料庫中取出資料,在模板 html 上進行頁面渲染資料 返回到使用者的瀏覽器上
urls 操作
url(r'^路由對映/', views.函式名),
url(r'^register/', views.register),
url(r'^路由對映-(?P<形參名>\d+).html', views.函式名),
url(r'^detail-(?P<cid>\d+).html', views.detail),
url(r'路由對映',include("app名稱.urls"))
url(r'app02',include("app02.urls"))
注:include 內參數加引號,urls 需要自己建立
在使用者建立的 urls 中,繼續進行地址對映,寫在 urlpatterns = [ ]中
app 不要忘記在 settings 中進行註冊
models 操作
建立資料表時,繼承 models.Model
示例
class UserInfo(models.Model)
建立字串型別資料 models.CharField
示例
username = models.CharField(max_length=32)
id 主鍵會自動建立,並遞增
使用 AutoField,並且宣告主鍵 primary_key=True 可以不讓系統建立 id 列
示例
uid = models.AutoField(primary_key=True)
欄位引數
null 欄位是否為空
default 預設值
示例
code = models.CharField(max_length=32,null=True,default="SA")
primary_key 主鍵
db_column 列名
db_index 索引 , unique 唯一索引
unique_for_date 對日期做索引,unique_for_month 對月做索引, unique_for_year 對年做索引
auto_now=True 建立時生成時間
示例
ctime = models.DateField(auto_now=True,null=True)
auto_now_add=True 修改時自動更新時間
choice 選項
示例 , choices 為 一個巢狀的元組物件
user_type_choices = (
(1,'super man'),
(2,'common man'),
(3,'man'),
)
user_type_id = models.IntegerField(choices=user_type_choices,default=2)
verbose_name 備註欄位
editable 欄位是否可以被編輯
help_text 欄位輸入提示
validators 自定義錯誤資訊
to_field 與哪一列進行關聯
建立整數型別資料 models.IntegerField
示例
user_type_id = models.IntegerField(choices=user_type_choices,default=2)
外來鍵關聯 models.ForeignKey
示例 第一個引數為類名,uid 為關聯的欄位
usergroup = models.ForeignKey('UserGroup',to_field='uid')
會自動生成 usergroup_id 列,usergroup 為物件,可以使用 usergroup.uid 進行獲取外聯表的資料
建立 ip
示例 , protocol預設為 'both'
ip = models.GenericIPAddressField(protocol="ipv4",db_index=True)
多對多 , 不能加額外欄位列
models.ManyToManyField('類名')
一對多,多對多示例
class Business(models.Model):
caption = models.CharField(max_length=32)
code = models.CharField(max_length=32,null=True,default="SA")
class Host(models.Model):
nid = models.AutoField(primary_key=True)
hostname = models.CharField(max_length=32,db_index=True)
ip = models.GenericIPAddressField(protocol="ipv4",db_index=True)
port = models.IntegerField()
b = models.ForeignKey(to="Business", to_field='id')
class Application(models.Model):
name = models.CharField(max_length=32)
r = models.ManyToManyField("Host")
注:會自動建立一個新的表,內部為其他表的 id 主鍵
obj = Application.objects.get(id=1)
增加資料
obj.r.add(1)
obj.r.add(1,2,3)
obj.r.add(*[1,2,3])
刪除資料
obj.r.remove(2,4,5)
obj.r.clear()
更新資料
obj.r.set([3,5,7])
多對多 , 自定義建立第三張表 , 可以自己定義第三張表的欄位
示例
class HostApp(models.Model):
hobj = models.ForeignKey(to='Host',to_field='nid')
aobj = models.ForeignKey(to='Application',to_field='id')
status = models.CharField(max_length=32)
增加資料
HostApp.objects.create(hobj_id='xxx',aobj='xxx',status='xxx')
html 操作
匯入 jquery
<script src="/static/jquery.min.js"></script>
匯入靜態檔案
<link rel="stylesheet" href="/static/commons.css">
使用 {{ 變數名 }} 進行顯示變數
<span style="color: red;">{{ error_msg }}</span>
for 迴圈
{% for 物件 in 傳遞過來字典的鍵 %}
<ul>
<li> {{ 物件 }} </li>
</ul>
{% endfor %}
遍歷字典中的鍵
{% for num in user_num.keys %}
<ul>
<li> {{ num }} </li>
</ul>
{% endfor %}
遍歷字典中的值
{% for num in user_num.values %}
<ul>
<li> {{ num }} </li>
</ul>
{% endfor %}
遍歷字典的所有元素
{% for key,value in user_num.items %}
<ul>
<li> {{ key }} - {{ value }}</li>
</ul>
{% endfor %}
遍歷列表
{% for name in user_list %}
<ul>
<li> {{ name }} </li>
</ul>
{% endfor %}
取索引物件
第一個元素
物件.0 {{ user_list.0 }}
對應索引元素名
物件.元素名 {{ user_num.zero }}
if 語句
{% if 條件%}
語句
{% else %}
語句
{% endif %}
{% if 條件 %}
語句
{% elif 條件 %}
語句
{% else %}
語句
{% endif %}
跳轉連結 href
<a href="app名稱/路由">內容</a>
示例 , 跳轉到 app02 下的 student 中
<a class="menu" href="/app02/student">學生管理</a>
迴圈計數 forloop
從 1 開始
{{ forloop.counter }}
從 0 開始
{{ forloop.counter0 }}
是否是第一個 , 返回 True 或 False
{{ forloop.first }}
是否是最後一個 , 返回 True 或 False
{{ forloop.last }}
倒序到 1 為止
{{ forloop.revcounter }}
倒序到 0 為止
{{ forloop.revcounter0 }}
上一層迴圈
{{ forloop.parentloop }}
ajax
$.ajax({
url:"路由地址",
type:"GET 或 POST 請求方式",
data:資料, data: $('#select 標籤的 id 值').serialize(), 獲取序列化資料
dataType:'資料型別'
success: function(data){
對獲取到的資料 data 要進行的操作
JSON.parse(data) 對返回的字串轉換為物件
location.reload(), 重新整理
location.href = '某個地址' , 跳轉
}
}
views 操作
形參可以使用 request , *args , **kwargs
request.method 提交方式
GET , POST 以及其他方式
request.environ 獲取所有的請求資訊
獲取 cookies
request.COOKIES
獲取使用者輸入的值
request.POST['html 中的name 屬性的值']
request.POST.get('html 中的name 屬性的值',None)
password = request.POST.get('password',None)
request.POST.getlist('html 中的name 屬性的值')
request.POST.getlist('favor')
返回頁面上顯示的字串
return HttpResponse('<標籤名>字串</標籤名>')
return HttpResponse('<h2>Hello</h2>')
頁面跳轉
return redirect('網址')
return redirect('/home/')
注: home 前面的 / 為 ip : 埠號/
頁面渲染
return render(request,'html檔名.html'[,變數])
return render(request,'login.html')
return render(request,'login.html',{'error_msg':error_msg})
注: 字典的鍵為在 html 中使用的變數名稱
資料庫增刪改查
欄位值大於 1 的
models.類名.objects.filter(欄位__gt=1)
欄位值大於等於 1 的
models.類名.objects.filter(欄位__gte=1)
欄位值等於 1 的
models.類名.objects.filter(欄位=1)
欄位值小於 1 的
models.類名.objects.filter(欄位__lt=1)
欄位值小於等於 1 的
models.類名.objects.filter(欄位__lte=1)
獲取指定欄位的值
models.類名.objects.all().values('欄位1','欄位2')
注:返回的是 QuerySet 型別,內部為字典物件
models.類名.objects.all().values_list('欄位1','欄位2')
注:返回的是 QuerySet 型別,內部為元組物件
示例
models.UserInfo.objects.all().values('username', 'password')
獲取檔案
注: 在檔案上傳時,在 form 表單中加入 enctype="multipart/form-data" 表示上傳的是檔案
上傳的檔案到 request.FILES 中進行查詢
file = request.FILES.get('html 中的name 屬性的值')
file.chunks() 一個可迭代物件,包含有上傳的檔案
file.name 檔名
file.size 檔案大小
獲取上傳檔案示例(fff 為 name 的值,upload為在專案根路徑下建立的資料夾):
file = request.FILES.get('fff')
import os
file_location = os.path.join('upload',file.name)
f = open(file_location,mode = 'wb')
for i in file.chunks():
f.write(i)
f.close()
根據使用者點選的不同,生成不同的詳細資訊
示例:
views 中:
user_info = {
'1':['xiaoming','nv','21'],
'2':['xiaolang','nan','22'],
'3':['xiaomi','nv','23'],
'4':['xiaole','nan','24'],
}
def index(request):
return render(request,'index.html',{'user_info':user_info})
def detail(request,cid):
detail_info = user_info[cid]
return render(request,'detail.html',{'detail_info':detail_info})
urls 中
url(r'^detail-(?P<cid>\d+).html',views.detail),
在括號中寫入 ?P<cid> 表示傳遞給形參 cid
html
index 中
{% for user_key in user_info.keys %}
<a href="/detail-{{ user_key }}.html">{{ user_key }}</a><br/>
{% endfor %}
detail 中
<h2>詳細資訊</h2>
<div style="margin: auto;color: burlywood">
使用者名稱:{{ detail_info.0 }}<br/>
性別:{{ detail_info.1 }}<br/>
年齡:{{ detail_info.2 }}<br/>
</div>
獲取當前 url
request.path_info
增加資料
第一種
models.類名.objects.create(
欄位1=值1,
欄位2=值2,
...
)
示例
models.UserInfo.objects.create(
username='www',
password='111'
)
第二種
obj = models.類名(欄位1=值1,欄位2=值2)
obj.save()
示例
obj = models.UserInfo(username='two',password='...')
obj.save()
查詢資料
查詢全部資料
models.類名.objects.all()
示例 username 為欄位名
all = models.UserInfo.objects.all()
for user in all:
print(user.username,user.password)
查詢指定某一行資料
models.類名.objects.filter(欄位1=值1[,欄位2=值2])
示例,對查詢到資料可以進行迴圈輸出資料
result = models.UserInfo.objects.filter(username='hany')
for user in result:
print(user.username,user.password)
示例 , 獲取外來鍵所在表的資料 , 外來鍵名為 b 通過.進行獲取資料,b_id 為在表中的欄位
v1 = models.Host.objects.filter(nid=1).first()
print(v1.nid,v1.hostname,v1.ip,v1.port,v1.b_id)
print(v1.b.id,v1.b.caption)
注:如果報錯,可以考慮使用 __ 進行查詢 b__caption
v2 = models.Host.objects.filter(nid=1)
print(v2.values('b__caption'))
刪除資料
刪除全部資料
models.類名.objects.all().delete()
示例
models.UserInfo.objects.all().delete()
刪除一條資料
models.類名.objects.filter(條件).delete()
示例
models.UserInfo.objects.filter(username='www').delete()
更新資料
更新全部資料
models.類名.objects.all().update(欄位=值)
示例
models.UserInfo.objects.all().update(password='666')
更新一條資料
models.類名.objects.filter(條件).update(欄位=值)
示例
models.UserInfo.objects.filter(id=1).update(password='111')
filter 後可以跟
count() 獲取資料個數
示例 , 當不存在對應資料時,obj_count 為 0
obj_count = models.UserInfo.objects.filter(username=username,password=password).count()
print(obj_count)
first() 獲取第一條資料
示例 , 使用了 first 之後,可以使用物件直接輸出欄位值
obj = models.UserInfo.objects.filter(username=username,password=password).first()
print(obj.username)
登入示例 , 沒有獲取到資料為 None
if not obj:
error_msg = 'name or password is error '
return render(request,'登入.html',{'error_msg':error_msg})
else:
return render(request, '主頁.html')
問題
SyntaxError: Generator expression must be parenthesized (widgets.py, line 152) 問題
去掉最後面的 , 號
跨站請求偽造 Forbidden (403) CSRF verification failed. Request aborted.
找到 settings 中的 MIDDLEWARE 將 csrf 註釋掉
You called this URL via POST, but the URL doesn't end in a slash and you have APPEND_SLASH set.
模板中提交的 action 資料要和 urls 的 urlpatterns 的 網址名稱一樣,要麼都帶 / , 要麼都不帶 /
2020-08-17