1. 程式人生 > 實用技巧 >django 武沛齊老師-最後一篇隨筆

django 武沛齊老師-最後一篇隨筆

基礎
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