<p><input type="text" name="name" placeholder="老師姓名" /></p> placeholder 默認顯示的字符信息 <select multiple size="10" name="class_ids"> multiple 多選 size 框大小 1. 母版 layout.html {% block x1 %}{%endblock%} <h1>ff</h1> {% block x2 %}{%endblock%} <h1>2</h1>... {% block x3 %}{%endblock%} index.html {%extends 'layout'%} {% block x1 %}dfssssssdfsd{%endblock%} {% block x2 %}dfsdfsd{%endblock%} {% block x3 %}fff{%endblock%} 3. Cookie 在瀏覽器上保存的鍵值對 def index(request): request.COOKIES request.get_signed_cookie('k1',salt='ff') obj = HttpReponse(..) obj = render(...) obj = redirect(..) obj.set_cookie(k1,v1,max_age) obj.set_signed_cookie(k1,v1,max_age,salt='fff') 4. BootStrap響應式佈局 - css - js(欠) 5. 後臺佈局 1. position: absolute 2. .c1:hover .c2{ } 坦白: project - app01 本身建立的目錄, - views.py - SQLHelper 封裝SQL操做 Django: - 路由 - 視圖 - 模板 - ORM(類-表;對象-行; pymysql鏈接數據庫) Torando: - 路由 - 視圖 - 模板 - 自由:pymysql;SqlAchemy Flask: - 路由 - 視圖 - 模板(第三方的組件) - 自由:pymysql;SqlAchemy 1. 建立app 2. 數據庫操做 Django目錄介紹 django-admin startproject mysite cd mysite python manage.py starapp app01 project - app01 - admin Django自帶後臺管理相關配置 - modal 寫類,根據類建立數據庫表 - test 單元測試 - views 業務處理 - app02 - app03 1. 路由系統 url -> 函數 a. /login/ -> def login b. /add-user/(\d+)/ -> def add_user(request,a1) c. /add-user/(?P<a1>\d+)/ -> def add_user(request,a1) PS: 終止符: ^edit$ 僞靜態 url(r'^edit/(\w+).html$', views.edit), d. 路由分發 urls.py url(r'^app01/', include('app01.urls')), app01.urls.py url(r'^index.html$', views.index), e. /add-user/(\d+)/ -> def add_user(request,a1) name=n1 根據名稱能夠反向生成URL 1. 在Python代碼中 from django.urls import reverse v = reverse('n1',kwargs={'a1':1111}) print(v) 2. url(r'^login/', views.login,name='m1') {% url "m1" %} cookies 相關 設置cookie set_cookie key value 設置超時時間 推薦使用max_age= 秒 expires=指定的日期 配合datatime使用 path 默認是'/' 指定url訪問cookie domain 域名劃分 默認當前域名 通常用不到 sso 統一認證登陸 會用到 安全相關 secure=False 給https提供的功能 httponly=False 等於true的時候,只能經過http請求發送,js代碼沒法獲取到 cookie簽名 set_signed_cookie key= '' value='' salt='加密' 相似MD5中的加鹽 獲取 res = request.get_signedcookie(key,salt='') 自定製簽名 裝飾器 登陸認證 內容整理 1 bootstrap 響應式佈局 @media() 最大寬度 2 柵格: 分紅12分 隨着寬度改變 樣式改變 3 表格 4 導航條 5 路徑導航 6 fontawesome 圖標 7 佈局 positione:absolute fix 固定位置 內容 overflout 8 .xx:hover .xx{ } 當鼠標移動的xx樣式的標籤上時,其子標籤的xx應用如下的屬性 9 django母版 共同的東西只寫一遍 母版: { % block s1 % } { % endblock% } 子版 {% extends "layout.html "%} { % block s1 % } ... ... { % endblock% } 10 用戶登陸 -cookie: 保存在瀏覽器端的鍵值對 設置超時時間 path domain 等參數 發送http請求時,在請求頭中攜帶當前全部訪問的cookie 在響應頭中 - 寫cookie @xzxx def index(request): obj = HttpResponse('...') obj.set_cookie(.....) request.COOKIES.get(...) 或者 obj.set_signed_cookie(.....) request.get_signed_cookie(....) - 自定義cookie簽名 - 裝飾器裝飾views中的函數 檢測用戶登陸 練習 今日做業: 1. 佈局+代碼 2. 登陸+cookie+裝飾器 3. 佈局頁面HTML+CSS django 路由 1 一對一路由 一個url 對應一個函數 url -> 函數 a. /login/ -> def login b. /add-user/(\d+)/ -> def add_user(request,a1) c. /add-user/(?P<a1>\d+)/ -> def add_user(request,a1) 2 正則表達式路由 3 路由分發 針對不一樣app from django.urls import path,re_path,include incloud('xxx') 字符串 path('app01/', include('app01.urls')), app01 re_path('edit/(\w+)/', views.edit), 路由中別名name re_path('edit/(\w+)/', views.edit,name='n1'), html action=「{% url "n1" X %}」 反轉url 路由 reverce 函數內部處理 from django.urls import reverse url = reverse(viewname,args=('',)或者kwargs={'a1':'xxx',}) print(reverse("n1",args=(123,))) 4 終止符 $ 正則匹配路由,以$結尾, ^edit$ 5 僞靜態 xxx.html$ 路由中必須已index$ 結尾。 僞靜態 url(r'^edit/(\w+).html$', views.edit), django ORM操做 Http請求: url -> 視圖(模板+數據) 鏈接數據庫操做步驟: 1. 建立數據庫 2. 修改project中默認鏈接sqlit爲mysql ,setting中設置 DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME':'s4day70db', 數據庫名稱 'USER': 'root', 'PASSWORD': '', 'HOST': 'localhost', 'PORT': 3306, } } 3. 在同project同名文件下的init.py 添加 不然會用默認的工具連接mysql import pymysql pymysql.install_as_MySQLdb() 4 建立表 app01 models中 from django.db import models # Create your models here. class UserInfo(models.Model): nid = models.BigAutoField(primary_key=True) #默認會建立一列id自增主鍵 username = models.CharField(max_length=32) #CharField 必須有max_length password = models.CharField(max_length=64) 5 註冊app setting中 INSTALLED_APPS 添加app的名字 「 」 6 建立數據表 終端執行 ********** python manage.py makemigrations python manage.py migrate 7 建立數據表 class UserGroup(models.Model): ''' 部門 ''' title = models.CharField(max_length=32) class UserInfo(models.Model): ''' 員工 ''' nid = models.BigAutoField(primary_key=True) username = models.CharField(max_length=32) password = models.CharField(max_length=64) age = models.IntegerField(default=1) #建立外鍵 生成的列名爲 ug_id ug = models.ForeignKey('UserGroup',null=True) 8 單表操做 class UserGroup(models.Model): """ 部門 """ title = models.CharField(max_length=32) --------------------------------------------------- """ 添加 models.UserGroup.objects.create(title='銷售部') 刪除 models.UserGroup.objects.filter(id=2).delete() 更新 models.UserGroup.objects.filter(id=2).update(title='公關部') 查詢 group_list = models.UserGroup.objects.all() 默認都是Queryset[obj,obj,] 只查詢第一個 就不是queryset類型,直接是第一個對象 group_list = models.UserGroup.objects.all().first() 查詢條件 group_list = models.UserGroup.objects.filter(id=1) group_list = models.UserGroup.objects.filter(id__gt=1) group_list = models.UserGroup.objects.filter(id__lt=1) """ 修改數據庫: 直接修更名稱 而後執行兩條命令 age = models.IntegerField(null=True) 或者default=1, #外鍵 連表操做 跨表去數據 針對對象 基礎語法 # 獲取 # QuerySet[obj,obj,obj] # result = models.UserInfo.objects.all() # for obj in result: # print(obj.name,obj.age,obj.ut_id,obj.ut.title) # UserInfo,ut是FK字段 - 正向操做 PS: 一個用戶只有一個用戶類型 # obj = models.UserInfo.objects.all().first() # print(obj.name,obj.age,obj.ut.title) # UserType, 表名小寫_set.all() - 反向操做 PS: 一個用戶類型下能夠有不少用戶 # obj = models.UserType.objects.all().first() # print('用戶類型',obj.id,obj.title) # for row in obj.userinfo_set.all(): # print(row.name,row.age) # 數據獲取多個數據時 all values values_list # 1. [obj,obj,obj,] # models.UserInfo.objects.all() # models.UserInfo.objects.filter(id__gt=1) # result = models.UserInfo.objects.all() # for item in result: # print(item.name,item.ut.title) # 2. [{id:1,name:fd},{id:1,name:fd},{id:1,name:fd},] # models.UserInfo.objects.all().values('id','name') # models.UserInfo.objects.filter(id__gt=1).values('id','name') # 沒法跨表 當前字典內沒連表的內容,後續也沒法跨表 # result = models.UserInfo.objects.all().values('id','name') # for item in result: # print(item['id'],item['name']) # # 誇表 雙下劃線 __ 把連表的值 也取到字典內 # result = models.UserInfo.objects.all().values('id','name',"ut__title") # for item in result: # print(item['id'],item['name'],item['ut__title']) # 3. [(1,df),(2,'df')] # models.UserInfo.objects.all().values_list('id','name') # models.UserInfo.objects.filter(id__gt=1).values_list('id','name') # 沒法跨表 # result = models.UserInfo.objects.all().values_list('id','name') # for item in result: # print(item[0],item[1]) # 誇表 __ # result = models.UserInfo.objects.all().values_list('id','name',"ut__title") # for item in result: # print(item[0],item[1],item[2]) # 3. 排序 user_list = models.UserInfo.objects.all().order_by('-id','name') # 4. 分組 from django.db.models import Count,Sum,Max,Min # v =models.UserInfo.objects.values('ut_id').annotate(xxxx=Count('id')) # print(v.query) # v =models.UserInfo.objects.values('ut_id').annotate(xxxx=Count('id')).filter(xxxx__gt=2) # print(v.query) # v =models.UserInfo.objects.filter(id__gt=2).values('ut_id').annotate(xxxx=Count('id')).filter(xxxx__gt=2) # print(v.query) # 5. F,更新時用於獲取原來的值 from django.db.models import F,Q # models.UserInfo.objects.all().update(age=F("age")+1) # 6. Q,用於構造複雜查詢條件 Q使用有兩種方式:對象方式,方法方式 # 應用一:對象方式 # models.UserInfo.objects.filter(Q(id__gt=1)) # models.UserInfo.objects.filter(Q(id=8) | Q(id=2)) # models.UserInfo.objects.filter(Q(id=8) & Q(id=2)) # 應用二:方法方式 # q1 = Q() # q1.connector = 'OR' # q1.children.append(('id__gt', 1)) # q1.children.append(('id', 10)) # q1.children.append(('id', 9)) # # # q2 = Q() # q2.connector = 'OR' # q2.children.append(('c1', 1)) # q2.children.append(('c1', 10)) # q2.children.append(('c1', 9)) # # q3 = Q() # q3.connector = 'AND' # q3.children.append(('id', 1)) # q3.children.append(('id', 2)) # q2.add(q3,'OR') # # con = Q() # con.add(q1, 'AND') # con.add(q2, 'AND') #例子 # 排序 # user_list = models.UserInfo.objects.all().order_by('-id','name') # print(user_list) # 分組 from django.db.models import Count,Sum,Max,Min # v =models.UserInfo.objects.values('ut_id').annotate(xxxx=Count('id')) # print(v.query) # v =models.UserInfo.objects.values('ut_id').annotate(xxxx=Count('id')).filter(xxxx__gt=2) # print(v.query) # v =models.UserInfo.objects.filter(id__gt=2).values('ut_id').annotate(xxxx=Count('id')).filter(xxxx__gt=2) # print(v.query) # 過濾 # models.UserInfo.objects.filter(id__gt=1) # models.UserInfo.objects.filter(id__lt=1) # models.UserInfo.objects.filter(id__lte=1) # models.UserInfo.objects.filter(id__gte=1) # models.UserInfo.objects.filter(id__in=[1,2,3]) # models.UserInfo.objects.filter(id__range=[1,2]) # models.UserInfo.objects.filter(name__startswith='xxxx') # models.UserInfo.objects.filter(name__contains='xxxx') # models.UserInfo.objects.exclude(id=1) # F,Q,extra # from django.db.models import F # models.UserInfo.objects.all().update(age=F("age")+1) # Q # models.UserInfo.objects.filter(id=1,name='root') # condition = { # 'id':1, # 'name': 'root' # } # models.UserInfo.objects.filter(**condition) # Q使用有兩種方式:對象方式,方法方式* # from django.db.models import Q # models.UserInfo.objects.filter(Q(id__gt=1)) # models.UserInfo.objects.filter(Q(id=8) | Q(id=2)) # models.UserInfo.objects.filter(Q(id=8) & Q(id=2)) # q1 = Q() # q1.connector = 'OR' # q1.children.append(('id__gt', 1)) # q1.children.append(('id', 10)) # q1.children.append(('id', 9)) # # # q2 = Q() # q2.connector = 'OR' # q2.children.append(('c1', 1)) # q2.children.append(('c1', 10)) # q2.children.append(('c1', 9)) # # q3 = Q() # q3.connector = 'AND' # q3.children.append(('id', 1)) # q3.children.append(('id', 2)) # q2.add(q3,'OR') # # con = Q() # con.add(q1, 'AND') # con.add(q2, 'AND') # condition_dict = { # 'k1':[1,2,3,4], # 'k2':[1,], # } # con = Q() # for k,v in condition_dict.items(): # q = Q() # q.connector = 'OR' # for i in v: # q.children.append(('id', i)) # con.add(q,'AND') # models.UserInfo.objects.filter(con) # # q1 = Q() # q1.connector = 'OR' # q1.children.append(('id', 1)) # q1.children.append(('id', 10)) # q1.children.append(('id', 9)) # # # q2 = Q() # q2.connector = 'OR' # q2.children.append(('c1', 1)) # q2.children.append(('c1', 10)) # q2.children.append(('c1', 9)) # # q3 = Q() # q3.connector = 'AND' # q3.children.append(('id', 1)) # q3.children.append(('id', 2)) # q2.add(q3,'OR') # # con = Q() # con.add(q1, 'AND') # con.add(q2, 'AND') # (id=1 or id = 10 or id=9 or (id=1 and id=2)) and (c1=1 or c1=10 or c1=9) # 7. extra, 額外查詢條件以及相關表,排序 models.UserInfo.objects.filter(id__gt=1) models.UserInfo.objects.all() # id name age ut_id models.UserInfo.objects.extra(self, select=None, where=None, params=None, tables=None, order_by=None, select_params=None) # a. 映射 # select # select_params=None # select 此處 from 表 # b. 條件 # where=None # params=None, # select * from 表 where 此處 # c. 表 # tables # select * from 表,此處 # c. 排序 # order_by=None # select * from 表 order by 此處 models.UserInfo.objects.extra( select={'newid':'select count(1) from app01_usertype where id>%s'}, select_params=[1,], where = ['age>%s'], params=[18,], order_by=['-age'], tables=['app01_usertype'] ) """ select app01_userinfo.id, (select count(1) from app01_usertype where id>1) as newid from app01_userinfo,app01_usertype where app01_userinfo.age > 18 order by app01_userinfo.age desc """ result = models.UserInfo.objects.filter(id__gt=1).extra( where=['app01_userinfo.id < %s'], params=[100,], tables=['app01_usertype'], order_by=['-app01_userinfo.id'], select={'uid':1,'sw':"select count(1) from app01_userinfo"} ) print(result.query) # SELECT (1) AS "uid", (select count(1) from app01_userinfo) AS "sw", "app01_userinfo"."id", "app01_userinfo"."name", "app01_userinfo"."age", "app01_userinfo"."ut_id" FROM "app01_userinfo" , "app01_usertype" WHERE ("app01_userinfo"."id" > 1 AND (app01_userinfo.id < 100)) ORDER BY ("app01_userinfo".id) DESC # 8. 原生SQL語句 from django.db import connection, connections cursor = connection.cursor() # connection=default數據 cursor = connections['db2'].cursor() #setting中的database名稱 cursor.execute("""SELECT * from auth_user where id = %s""", [1]) row = cursor.fetchone() row = cursor.fetchall() - 原生SQL語句 - raw result = models.UserInfo.objects.raw('select * from userinfo') [obj(UserInfo),obj,] result = models.UserInfo.objects.raw('select id,1 as name,2 as age,4 as ut_id from usertype') [obj(UserInfo),obj,] v1 = models.UserInfo.objects.raw('SELECT id,title FROM app01_usertype',translations=name_map) # 9. 簡單的操做 http://www.cnblogs.com/wupeiqi/articles/6216618.html 9 其餘 http://www.cnblogs.com/wupeiqi/articles/6216618.html 其餘操做 # v = models.UserInfo.objects.all().only('id','name') # v = models.UserInfo.objects.all().defer('name') 除了name列 models.UserInfo.objects.all().using('db2') 用哪一個數據庫 setting中database的 . models.UserInfo.objects.all().filter().all().exclude().only().defer() 能夠一直去下去 由於是queryset類型的對象 有。方法,別的不行 分組 aggregate distinct # models.UserInfo.objects.none() # result = models.UserInfo.objects.aggregate(k=Count('ut_id', distinct=True), n=Count('id')) # print(result) #新增 返回的對象 就是新增的數據 # obj = models.UserType.objects.create(title='xxx') # obj = models.UserType.objects.create(**{'title': 'xxx'}) # print(obj.id) save保存後纔會數據庫建立 # obj = models.UserType(title='xxx') # obj.save() 批量增長 def bulk_create(self, objs, batch_size=None): # 批量插入 # batch_size表示一次插入的個數 objs = [ models.DDD(name='r11'), models.DDD(name='r22') ] models.DDD.objects.bulk_create(objs, 10) def get_or_create(self, defaults=None, **kwargs): # 若是存在,則獲取,不然,建立 # defaults 指定建立時,其餘字段的值 obj, created = models.UserInfo.objects.get_or_create(username='root1', defaults={'email': '1111111','u_id': 2, 't_id': 2}) created 返回的爲 True或者是false def update_or_create(self, defaults=None, **kwargs): # 若是存在,則更新,不然,建立 # defaults 指定建立時或更新時的其餘字段 obj, created = models.UserInfo.objects.update_or_create(username='root1', defaults={'email': '1111111','u_id': 2, 't_id': 1}) 根據主鍵查詢 # models.UserInfo.objects.filter(id__in=[1,2,3]) # models.UserInfo.objects.in_bulk([1,2,3]) ==========================補充1==========================select_related prefetch_related # q = models.UserInfo.objects.all() # select * from userinfo # select * from userinfo inner join usertype on ... # for row in q: # print(row.name,row.ut.title) # select_related: 查詢主動作連表 # q = models.UserInfo.objects.all().select_related('ut','gp') # select * from userinfo # select * from userinfo inner join usertype on ... # for row in q: # print(row.name,row.ut.title) # prefetch_related: 不作連表,作屢次查詢 # q = models.UserInfo.objects.all().prefetch_related('ut') # select * from userinfo; # Django內部:ut_id = [2,4] # select * from usertype where id in [2,4] # for row in q: # print(row.id,row.ut.title) # 多對多 # objs = [ # models.Boy(name='方少偉'), # models.Boy(name='由秦兵'), # models.Boy(name='陳濤'), # models.Boy(name='閆龍'), # models.Boy(name='吳彥祖'), # ] # models.Boy.objects.bulk_create(objs,5) # # objss = [ # models.Girl(nick='小魚'), # models.Girl(nick='小周'), # models.Girl(nick='小貓'), # models.Girl(nick='小狗'), # ] # models.Girl.objects.bulk_create(objss,5) # models.Love.objects.create(b_id=1,g_id=1) # models.Love.objects.create(b_id=1,g_id=4) # models.Love.objects.create(b_id=2,g_id=4) # models.Love.objects.create(b_id=2,g_id=2) # 1. 和方少偉有關係的姑娘 # obj = models.Boy.objects.filter(name='方少偉').first() # love_list = obj.love_set.all() # for row in love_list: # print(row.g.nick) # # # love_list = models.Love.objects.filter(b__name='方少偉') # for row in love_list: # print(row.g.nick) # # love_list = models.Love.objects.filter(b__name='方少偉').values('g__nick') # for item in love_list: # print(item['g__nick']) # # love_list = models.Love.objects.filter(b__name='方少偉').select_related('g') # for obj in love_list: # print(obj.g.nick) 第三章關係表 能夠本身定義類 或者使用內置的生成,可是隻能生成三列,二者合用 # m = models.ManyToManyField('Boy') 生成第三張關係表 #m = models.ManyToManyField('Girl',through="Love",through_fields=('b','g',)) 告訴django經過love鏈接,love表的b','g', 來關聯 只提供查詢和清空的功能 class Boy(models.Model): name = models.CharField(max_length=32) m = models.ManyToManyField('Girl',through="Love",through_fields=('b','g',)) class Girl(models.Model): nick = models.CharField(max_length=32) # m = models.ManyToManyField('Boy') class Love(models.Model): b = models.ForeignKey('Boy') g = models.ForeignKey('Girl') #聯合惟一索引 class Meta: unique_together = [ ('b','g'), ] # obj = models.Boy.objects.filter(name='方少偉').first() # print(obj.id,obj.name) # obj.m.add(2) # obj.m.add(2,4) # obj.m.add(*[1,]) # obj.m.remove(1) # obj.m.remove(2,3) # obj.m.remove(*[4,]) # obj.m.set([1,]) # q = obj.m.all() # # [Girl對象] # print(q) # obj = models.Boy.objects.filter(name='方少偉').first() # girl_list = obj.m.all() # obj = models.Boy.objects.filter(name='方少偉').first() # girl_list = obj.m.all() # girl_list = obj.m.filter(nick='小魚') # print(girl_list) # obj = models.Boy.objects.filter(name='方少偉').first() # obj.m.clear() # obj = models.Girl.objects.filter(nick='小魚').first() # print(obj.id,obj.nick) # v = obj.boy_set.all() # print(v) 編寫ORM app01 -- models 中 建立表 ORM操做表: 建立表 修改表 刪除表 操做數據行: 增刪改查 ORM利用pymysql第三方工具鏈接數據庫 默認: SQLlite MySQL: mysql -> MySQLDB(修改django默認鏈接mySQL方式) XSS 跨站腳本攻擊 -慎用safe 和mark_safe(導入模塊 ) from django.utils.safestring import mark_safe safe 在html中代表 -非要用,必定要過濾關鍵字 csrf 通常post提交的時候驗證 FBv使用方法 a.基本應用 在form中添加 {% csrf_token %} {{ csrf_token }} 頁面會顯示隨機字符串信息 b. 全局禁用 setting中 'django.middleware.csrf.CsrfViewMiddleware', 註釋 c. 局部禁用 全局使用,在函數上添加裝飾器 from django.views.decorators.csrf import csrf_exempt @csrf_exempt def index(): pass d.局部使用 全局禁用 在函數上添加裝飾器 from django.views.decorators.csrf import csrf_protect @csrf_protect def index(): pass CBV使用裝飾器方法 from django.views import View from django.utils.decorators import method_decorator # 1. CBV應用裝飾器 def wrapper(func): def inner(*args,**kwargs): return func(*args,**kwargs) return inner # 1. 指定方法上添加裝飾器 # class Foo(View): # # @method_decorator(csrf_protect) # def get(self,request): # pass # # def post(self,request): # pass # 2. 在類上添加 # @method_decorator(csrf_protect,name='dispatch') #cbv中全部的提交都會先到dispatch # class Foo(View): # # def get(self,request): # pass # # def post(self,request): # pass Ajax提交數據時候,攜帶CSRF: a. 放置在data中攜帶 <form method="POST" action="/csrf1.html"> {% csrf_token %} <input id="user" type="text" name="user" /> <input type="submit" value="提交"/> <a onclick="submitForm();">Ajax提交</a> </form> <script src="/static/jquery-1.12.4.js"></script> <script> function submitForm(){ var csrf = $('input[name="csrfmiddlewaretoken"]').val(); var user = $('#user').val(); $.ajax({ url: '/csrf1.html', type: 'POST', data: { "user":user,'csrfmiddlewaretoken': csrf}, success:function(arg){ console.log(arg); } }) } </script> b. 放在請求頭中 <form method="POST" action="/csrf1.html"> {% csrf_token %} <input id="user" type="text" name="user" /> <input type="submit" value="提交"/> <a onclick="submitForm();">Ajax提交</a> </form> <script src="/static/jquery-1.12.4.js"></script> <script src="/static/jquery.cookie.js"></script> <script> function submitForm(){ var token = $.cookie('csrftoken'); var user = $('#user').val(); $.ajax({ url: '/csrf1.html', type: 'POST', headers:{'X-CSRFToken': token}, data: { "user":user}, success:function(arg){ console.log(arg); } }) } </script> django視圖 cbv 、 fbv CBV 先dispatch 判斷method 反射 若是想作定製化的 能夠添加在這裏 def dispatch(self, request, *args, **kwargs): print("before") obj=super(Login, self).dispatch(request,*args,**kwargs) print("after") return obj url中設置 re_path('classes/',views.Login.as_view),固定用法 view設置爲 form表單只有post 和 get 方法,ajex 支持全部 from django.views import View class Login(View): ''' 請求方法基本經常使用的 get 查詢 post 建立 put 更新 delete 刪除 ''' def dispatch(self, request, *args, **kwargs): print("before") obj=super(Login, self).dispatch(request,*args,**kwargs) print("after") return obj def get(self,request): pass def put(self,request): pass django 分頁操做 分批獲取數據 models.UserInfo.objects.all()[0:10] models.UserInfo.objects.all()[10:20] ---django 自帶提供的的分頁 from django.core.paginator import Paginator,Page,PageNotAnInteger,EmptyPage def index(request): """ 分頁 :param request: :return: """ # for i in range(300): # name = "root" + str(i) # models.UserInfo.objects.create(name=name,age=18,ut_id=1) current_page = request.GET.get('page') user_list = models.UserInfo.objects.all() paginator = Paginator(user_list,10) # per_page: 每頁顯示條目數量 # count: 數據總個數 # num_pages:總頁數 # page_range:總頁數的索引範圍,如: (1,10),(1,200) # page: page對象 try: posts = paginator.page(current_page) except PageNotAnInteger as e: posts = paginator.page(1) except EmptyPage as e: posts = paginator.page(1) # has_next 是否有下一頁 # next_page_number 下一頁頁碼 # has_previous 是否有上一頁 # previous_page_number 上一頁頁碼 # object_list 分頁以後的數據列表 # number 當前頁 # paginator paginator對象 return render(request,'index.html',{'posts':posts}) --自定義分頁組件 from utils.pager import PageInfo def custom(request): # 表示用戶當前想要訪問的頁碼: 8 all_count = models.UserInfo.objects.all().count() page_info = PageInfo(request.GET.get('page'),all_count,10,'/custom.html',11) user_list = models.UserInfo.objects.all()[page_info.start():page_info.end()] return render(request,'custom.html',{'user_list':user_list,'page_info':page_info}) class PageInfo(object): def __init__(self,current_page,all_count,per_page,base_url,show_page=11): """ :param current_page: :param all_count: 數據庫總行數 :param per_page: 每頁顯示函數 :return: """ try: self.current_page = int(current_page) except Exception as e: self.current_page = 1 self.per_page = per_page a,b = divmod(all_count,per_page) if b: a = a +1 self.all_pager = a self.show_page = show_page self.base_url = base_url def start(self): return (self.current_page-1) * self.per_page def end(self): return self.current_page * self.per_page def pager(self): # v = "<a href='/custom.html?page=1'>1</a><a href='/custom.html?page=2'>2</a>" # return v page_list = [] half = int((self.show_page-1)/2) # 若是數據總頁數 < 11 if self.all_pager < self.show_page: begin = 1 stop = self.all_pager + 1 # 若是數據總頁數 > 11 else: # 若是當前頁 <=5,永遠顯示1,11 if self.current_page <= half: begin = 1 stop = self.show_page + 1 else: if self.current_page + half > self.all_pager: begin = self.all_pager - self.show_page + 1 stop = self.all_pager + 1 else: begin = self.current_page - half stop = self.current_page + half + 1 if self.current_page <= 1: prev = "<li><a href='#'>上一頁</a></li>" else: prev = "<li><a href='%s?page=%s'>上一頁</a></li>" %(self.base_url,self.current_page-1,) page_list.append(prev) for i in range(begin,stop): if i == self.current_page: temp = "<li class='active'><a href='%s?page=%s'>%s</a></li>" %(self.base_url,i,i,) else: temp = "<li><a href='%s?page=%s'>%s</a></li>" %(self.base_url,i,i,) page_list.append(temp) if self.current_page >= self.all_pager: nex = "<li><a href='#'>下一頁</a></li>" else: nex = "<li><a href='%s?page=%s'>下一頁</a></li>" %(self.base_url,self.current_page+1,) page_list.append(nex) return ''.join(page_list) <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> <link rel="stylesheet" href="/static/plugins/bootstrap-3.3.7-dist/css/bootstrap.css" /> </head> <body> <h1>用戶列表</h1> <ul> {% for row in user_list %} <li>{{ row.name }}</li> {% endfor %} </ul> <nav aria-label="Page navigation"> <ul class="pagination"> {{ page_info.pager|safe }} </ul> </nav> </body> </html>
<p><input type="text" name="name" placeholder="老師姓名" /></p>
placeholder 默認顯示的字符信息
<select multiple size="10" name="class_ids"> multiple 多選 size 框大小
1. 母版layout.html{% block x1 %}{%endblock%}<h1>ff</h1>{% block x2 %}{%endblock%}<h1>2</h1>...{% block x3 %}{%endblock%}index.html{%extends 'layout'%}{% block x1 %}dfssssssdfsd{%endblock%}{% block x2 %}dfsdfsd{%endblock%}{% block x3 %}fff{%endblock%}3. Cookie在瀏覽器上保存的鍵值對def index(request):request.COOKIESrequest.get_signed_cookie('k1',salt='ff')obj = HttpReponse(..)obj = render(...)obj = redirect(..)obj.set_cookie(k1,v1,max_age)obj.set_signed_cookie(k1,v1,max_age,salt='fff')4. BootStrap響應式佈局- css- js(欠)5. 後臺佈局1. position: absolute2. .c1:hover .c2{}坦白:project- app01 本身建立的目錄,- views.py- SQLHelper 封裝SQL操做Django:- 路由- 視圖- 模板- ORM(類-表;對象-行; pymysql鏈接數據庫)Torando:- 路由- 視圖- 模板- 自由:pymysql;SqlAchemyFlask:- 路由- 視圖- 模板(第三方的組件)- 自由:pymysql;SqlAchemy1. 建立app2. 數據庫操做
Django目錄介紹django-admin startproject mysitecd mysitepython manage.py starapp app01project- app01- admin Django自帶後臺管理相關配置- modal 寫類,根據類建立數據庫表- test 單元測試- views 業務處理- app02- app03
1. 路由系統url -> 函數a. /login/ -> def loginb. /add-user/(\d+)/ -> def add_user(request,a1)c. /add-user/(?P<a1>\d+)/ -> def add_user(request,a1)PS: 終止符:^edit$僞靜態url(r'^edit/(\w+).html$', views.edit),d. 路由分發urls.pyurl(r'^app01/', include('app01.urls')),app01.urls.pyurl(r'^index.html$', views.index),e. /add-user/(\d+)/ -> def add_user(request,a1) name=n1根據名稱能夠反向生成URL1. 在Python代碼中from django.urls import reversev = reverse('n1',kwargs={'a1':1111})print(v)2. url(r'^login/', views.login,name='m1'){% url "m1" %}
cookies 相關設置cookieset_cookiekeyvalue 設置超時時間 推薦使用max_age= 秒 expires=指定的日期 配合datatime使用
path 默認是'/' 指定url訪問cookie
domain 域名劃分 默認當前域名 通常用不到 sso 統一認證登陸 會用到
安全相關secure=False 給https提供的功能httponly=False 等於true的時候,只能經過http請求發送,js代碼沒法獲取到
cookie簽名set_signed_cookiekey= ''value=''salt='加密'相似MD5中的加鹽
獲取res = request.get_signedcookie(key,salt='')
自定製簽名
裝飾器 登陸認證
內容整理1 bootstrap 響應式佈局 @media() 最大寬度2 柵格:分紅12分 隨着寬度改變 樣式改變3 表格4 導航條
5 路徑導航
6 fontawesome 圖標
7 佈局 positione:absolute fix 固定位置內容 overflout
8 .xx:hover .xx{ }當鼠標移動的xx樣式的標籤上時,其子標籤的xx應用如下的屬性
9 django母版 共同的東西只寫一遍母版:{ % block s1 % }
{ % endblock% }
子版{% extends "layout.html "%}{ % block s1 % }......{ % endblock% }
10 用戶登陸 -cookie: 保存在瀏覽器端的鍵值對 設置超時時間 path domain 等參數 發送http請求時,在請求頭中攜帶當前全部訪問的cookie 在響應頭中
- 寫cookie@xzxxdef index(request):obj = HttpResponse('...')obj.set_cookie(.....)request.COOKIES.get(...)或者obj.set_signed_cookie(.....)request.get_signed_cookie(....)
- 自定義cookie簽名- 裝飾器裝飾views中的函數 檢測用戶登陸
練習今日做業:1. 佈局+代碼2. 登陸+cookie+裝飾器3. 佈局頁面HTML+CSS
django 路由
1 一對一路由 一個url 對應一個函數url -> 函數a. /login/ -> def loginb. /add-user/(\d+)/ -> def add_user(request,a1)c. /add-user/(?P<a1>\d+)/ -> def add_user(request,a1)
2 正則表達式路由
3 路由分發 針對不一樣app from django.urls import path,re_path,includeincloud('xxx') 字符串
path('app01/', include('app01.urls')),
app01 re_path('edit/(\w+)/', views.edit),
路由中別名name re_path('edit/(\w+)/', views.edit,name='n1'),
htmlaction=「{% url "n1" X %}」
反轉url 路由 reverce 函數內部處理from django.urls import reverseurl = reverse(viewname,args=('',)或者kwargs={'a1':'xxx',})print(reverse("n1",args=(123,)))
4 終止符 $正則匹配路由,以$結尾,^edit$
5 僞靜態 xxx.html$路由中必須已index$ 結尾。僞靜態url(r'^edit/(\w+).html$', views.edit),
django ORM操做
Http請求:url -> 視圖(模板+數據)
鏈接數據庫操做步驟:1. 建立數據庫
2. 修改project中默認鏈接sqlit爲mysql ,setting中設置DATABASES = {'default': {'ENGINE': 'django.db.backends.mysql','NAME':'s4day70db', 數據庫名稱'USER': 'root','PASSWORD': '','HOST': 'localhost', 'PORT': 3306,}}
3. 在同project同名文件下的init.py 添加 不然會用默認的工具連接mysqlimport pymysqlpymysql.install_as_MySQLdb()
4 建立表 app01 models中from django.db import models
# Create your models here.class UserInfo(models.Model): nid = models.BigAutoField(primary_key=True) #默認會建立一列id自增主鍵 username = models.CharField(max_length=32) #CharField 必須有max_length password = models.CharField(max_length=64)
5 註冊app setting中 INSTALLED_APPS 添加app的名字 「 」
6 建立數據表 終端執行 ********** python manage.py makemigrations python manage.py migrate
7 建立數據表class UserGroup(models.Model): ''' 部門 ''' title = models.CharField(max_length=32)
class UserInfo(models.Model): ''' 員工 ''' nid = models.BigAutoField(primary_key=True) username = models.CharField(max_length=32) password = models.CharField(max_length=64) age = models.IntegerField(default=1) #建立外鍵 生成的列名爲 ug_id ug = models.ForeignKey('UserGroup',null=True)
8 單表操做class UserGroup(models.Model): """ 部門 """ title = models.CharField(max_length=32) ---------------------------------------------------"""添加models.UserGroup.objects.create(title='銷售部')
刪除models.UserGroup.objects.filter(id=2).delete()
更新models.UserGroup.objects.filter(id=2).update(title='公關部')
查詢group_list = models.UserGroup.objects.all()默認都是Queryset[obj,obj,]
只查詢第一個 就不是queryset類型,直接是第一個對象group_list = models.UserGroup.objects.all().first()
查詢條件group_list = models.UserGroup.objects.filter(id=1)group_list = models.UserGroup.objects.filter(id__gt=1)group_list = models.UserGroup.objects.filter(id__lt=1)
"""
修改數據庫:直接修更名稱 而後執行兩條命令 age = models.IntegerField(null=True) 或者default=1,
#外鍵 連表操做 跨表去數據 針對對象 基礎語法 # 獲取 # QuerySet[obj,obj,obj] # result = models.UserInfo.objects.all() # for obj in result: # print(obj.name,obj.age,obj.ut_id,obj.ut.title)
# UserInfo,ut是FK字段 - 正向操做 PS: 一個用戶只有一個用戶類型 # obj = models.UserInfo.objects.all().first() # print(obj.name,obj.age,obj.ut.title)
# UserType, 表名小寫_set.all() - 反向操做 PS: 一個用戶類型下能夠有不少用戶 # obj = models.UserType.objects.all().first() # print('用戶類型',obj.id,obj.title) # for row in obj.userinfo_set.all(): # print(row.name,row.age)
# 數據獲取多個數據時 all values values_list # 1. [obj,obj,obj,] # models.UserInfo.objects.all() # models.UserInfo.objects.filter(id__gt=1) # result = models.UserInfo.objects.all() # for item in result: # print(item.name,item.ut.title)
# 2. [{id:1,name:fd},{id:1,name:fd},{id:1,name:fd},] # models.UserInfo.objects.all().values('id','name') # models.UserInfo.objects.filter(id__gt=1).values('id','name') # 沒法跨表 當前字典內沒連表的內容,後續也沒法跨表 # result = models.UserInfo.objects.all().values('id','name') # for item in result: # print(item['id'],item['name']) # # 誇表 雙下劃線 __ 把連表的值 也取到字典內 # result = models.UserInfo.objects.all().values('id','name',"ut__title") # for item in result: # print(item['id'],item['name'],item['ut__title'])
# 3. [(1,df),(2,'df')] # models.UserInfo.objects.all().values_list('id','name') # models.UserInfo.objects.filter(id__gt=1).values_list('id','name') # 沒法跨表 # result = models.UserInfo.objects.all().values_list('id','name') # for item in result: # print(item[0],item[1]) # 誇表 __ # result = models.UserInfo.objects.all().values_list('id','name',"ut__title") # for item in result: # print(item[0],item[1],item[2])
# 3. 排序user_list = models.UserInfo.objects.all().order_by('-id','name')# 4. 分組from django.db.models import Count,Sum,Max,Min# v =models.UserInfo.objects.values('ut_id').annotate(xxxx=Count('id'))# print(v.query)# v =models.UserInfo.objects.values('ut_id').annotate(xxxx=Count('id')).filter(xxxx__gt=2)# print(v.query)# v =models.UserInfo.objects.filter(id__gt=2).values('ut_id').annotate(xxxx=Count('id')).filter(xxxx__gt=2)# print(v.query)
# 5. F,更新時用於獲取原來的值from django.db.models import F,Q# models.UserInfo.objects.all().update(age=F("age")+1)
# 6. Q,用於構造複雜查詢條件Q使用有兩種方式:對象方式,方法方式# 應用一:對象方式# models.UserInfo.objects.filter(Q(id__gt=1))# models.UserInfo.objects.filter(Q(id=8) | Q(id=2))# models.UserInfo.objects.filter(Q(id=8) & Q(id=2))# 應用二:方法方式# q1 = Q()# q1.connector = 'OR'# q1.children.append(('id__gt', 1))# q1.children.append(('id', 10))# q1.children.append(('id', 9))### q2 = Q()# q2.connector = 'OR'# q2.children.append(('c1', 1))# q2.children.append(('c1', 10))# q2.children.append(('c1', 9))## q3 = Q()# q3.connector = 'AND'# q3.children.append(('id', 1))# q3.children.append(('id', 2))# q2.add(q3,'OR')## con = Q()# con.add(q1, 'AND')# con.add(q2, 'AND')
#例子 # 排序 # user_list = models.UserInfo.objects.all().order_by('-id','name') # print(user_list)
# 分組 from django.db.models import Count,Sum,Max,Min # v =models.UserInfo.objects.values('ut_id').annotate(xxxx=Count('id')) # print(v.query) # v =models.UserInfo.objects.values('ut_id').annotate(xxxx=Count('id')).filter(xxxx__gt=2) # print(v.query) # v =models.UserInfo.objects.filter(id__gt=2).values('ut_id').annotate(xxxx=Count('id')).filter(xxxx__gt=2) # print(v.query) # 過濾 # models.UserInfo.objects.filter(id__gt=1) # models.UserInfo.objects.filter(id__lt=1) # models.UserInfo.objects.filter(id__lte=1) # models.UserInfo.objects.filter(id__gte=1) # models.UserInfo.objects.filter(id__in=[1,2,3]) # models.UserInfo.objects.filter(id__range=[1,2]) # models.UserInfo.objects.filter(name__startswith='xxxx') # models.UserInfo.objects.filter(name__contains='xxxx') # models.UserInfo.objects.exclude(id=1)
# F,Q,extra # from django.db.models import F # models.UserInfo.objects.all().update(age=F("age")+1)
# Q # models.UserInfo.objects.filter(id=1,name='root')
# condition = { # 'id':1, # 'name': 'root' # } # models.UserInfo.objects.filter(**condition) # Q使用有兩種方式:對象方式,方法方式*
# from django.db.models import Q # models.UserInfo.objects.filter(Q(id__gt=1)) # models.UserInfo.objects.filter(Q(id=8) | Q(id=2)) # models.UserInfo.objects.filter(Q(id=8) & Q(id=2))
# q1 = Q() # q1.connector = 'OR' # q1.children.append(('id__gt', 1)) # q1.children.append(('id', 10)) # q1.children.append(('id', 9)) # # # q2 = Q() # q2.connector = 'OR' # q2.children.append(('c1', 1)) # q2.children.append(('c1', 10)) # q2.children.append(('c1', 9)) # # q3 = Q() # q3.connector = 'AND' # q3.children.append(('id', 1)) # q3.children.append(('id', 2)) # q2.add(q3,'OR') # # con = Q() # con.add(q1, 'AND') # con.add(q2, 'AND')
# condition_dict = { # 'k1':[1,2,3,4], # 'k2':[1,], # } # con = Q() # for k,v in condition_dict.items(): # q = Q() # q.connector = 'OR' # for i in v: # q.children.append(('id', i)) # con.add(q,'AND') # models.UserInfo.objects.filter(con) # # q1 = Q() # q1.connector = 'OR' # q1.children.append(('id', 1)) # q1.children.append(('id', 10)) # q1.children.append(('id', 9)) # # # q2 = Q() # q2.connector = 'OR' # q2.children.append(('c1', 1)) # q2.children.append(('c1', 10)) # q2.children.append(('c1', 9)) # # q3 = Q() # q3.connector = 'AND' # q3.children.append(('id', 1)) # q3.children.append(('id', 2)) # q2.add(q3,'OR') # # con = Q() # con.add(q1, 'AND') # con.add(q2, 'AND') # (id=1 or id = 10 or id=9 or (id=1 and id=2)) and (c1=1 or c1=10 or c1=9)
# 7. extra, 額外查詢條件以及相關表,排序models.UserInfo.objects.filter(id__gt=1)models.UserInfo.objects.all() # id name age ut_idmodels.UserInfo.objects.extra(self, select=None, where=None, params=None, tables=None, order_by=None, select_params=None)# a. 映射# select # select_params=None# select 此處 from 表# b. 條件# where=None# params=None,# select * from 表 where 此處# c. 表# tables# select * from 表,此處# c. 排序# order_by=None# select * from 表 order by 此處models.UserInfo.objects.extra(select={'newid':'select count(1) from app01_usertype where id>%s'},select_params=[1,],where = ['age>%s'],params=[18,],order_by=['-age'],tables=['app01_usertype'])"""select app01_userinfo.id,(select count(1) from app01_usertype where id>1) as newidfrom app01_userinfo,app01_usertypewhere app01_userinfo.age > 18order by app01_userinfo.age desc"""result = models.UserInfo.objects.filter(id__gt=1).extra(where=['app01_userinfo.id < %s'],params=[100,],tables=['app01_usertype'],order_by=['-app01_userinfo.id'],select={'uid':1,'sw':"select count(1) from app01_userinfo"})print(result.query)# SELECT (1) AS "uid", (select count(1) from app01_userinfo) AS "sw", "app01_userinfo"."id", "app01_userinfo"."name", "app01_userinfo"."age", "app01_userinfo"."ut_id" FROM "app01_userinfo" , "app01_usertype" WHERE ("app01_userinfo"."id" > 1 AND (app01_userinfo.id < 100)) ORDER BY ("app01_userinfo".id) DESC
# 8. 原生SQL語句from django.db import connection, connectionscursor = connection.cursor() # connection=default數據cursor = connections['db2'].cursor() #setting中的database名稱cursor.execute("""SELECT * from auth_user where id = %s""", [1])row = cursor.fetchone()row = cursor.fetchall()
- 原生SQL語句- rawresult = models.UserInfo.objects.raw('select * from userinfo')[obj(UserInfo),obj,]result = models.UserInfo.objects.raw('select id,1 as name,2 as age,4 as ut_id from usertype')[obj(UserInfo),obj,]v1 = models.UserInfo.objects.raw('SELECT id,title FROM app01_usertype',translations=name_map)# 9. 簡單的操做http://www.cnblogs.com/wupeiqi/articles/6216618.html
9 其餘 http://www.cnblogs.com/wupeiqi/articles/6216618.html 其餘操做 # v = models.UserInfo.objects.all().only('id','name') # v = models.UserInfo.objects.all().defer('name') 除了name列
models.UserInfo.objects.all().using('db2') 用哪一個數據庫 setting中database的 .
models.UserInfo.objects.all().filter().all().exclude().only().defer() 能夠一直去下去 由於是queryset類型的對象 有。方法,別的不行
分組 aggregate distinct # models.UserInfo.objects.none() # result = models.UserInfo.objects.aggregate(k=Count('ut_id', distinct=True), n=Count('id')) # print(result)
#新增 返回的對象 就是新增的數據 # obj = models.UserType.objects.create(title='xxx') # obj = models.UserType.objects.create(**{'title': 'xxx'}) # print(obj.id)
save保存後纔會數據庫建立 # obj = models.UserType(title='xxx') # obj.save()
批量增長def bulk_create(self, objs, batch_size=None): # 批量插入 # batch_size表示一次插入的個數 objs = [ models.DDD(name='r11'), models.DDD(name='r22') ] models.DDD.objects.bulk_create(objs, 10)
def get_or_create(self, defaults=None, **kwargs): # 若是存在,則獲取,不然,建立 # defaults 指定建立時,其餘字段的值 obj, created = models.UserInfo.objects.get_or_create(username='root1', defaults={'email': '1111111','u_id': 2, 't_id': 2})
created 返回的爲 True或者是false
def update_or_create(self, defaults=None, **kwargs): # 若是存在,則更新,不然,建立 # defaults 指定建立時或更新時的其餘字段 obj, created = models.UserInfo.objects.update_or_create(username='root1', defaults={'email': '1111111','u_id': 2, 't_id': 1})
根據主鍵查詢 # models.UserInfo.objects.filter(id__in=[1,2,3]) # models.UserInfo.objects.in_bulk([1,2,3])
==========================補充1==========================select_related prefetch_related# q = models.UserInfo.objects.all()# select * from userinfo# select * from userinfo inner join usertype on ...# for row in q:# print(row.name,row.ut.title)
# select_related: 查詢主動作連表# q = models.UserInfo.objects.all().select_related('ut','gp')# select * from userinfo# select * from userinfo inner join usertype on ...# for row in q:# print(row.name,row.ut.title)
# prefetch_related: 不作連表,作屢次查詢# q = models.UserInfo.objects.all().prefetch_related('ut')# select * from userinfo;# Django內部:ut_id = [2,4]# select * from usertype where id in [2,4]# for row in q:# print(row.id,row.ut.title)
# 多對多 # objs = [ # models.Boy(name='方少偉'), # models.Boy(name='由秦兵'), # models.Boy(name='陳濤'), # models.Boy(name='閆龍'), # models.Boy(name='吳彥祖'), # ] # models.Boy.objects.bulk_create(objs,5) # # objss = [ # models.Girl(nick='小魚'), # models.Girl(nick='小周'), # models.Girl(nick='小貓'), # models.Girl(nick='小狗'), # ] # models.Girl.objects.bulk_create(objss,5)
# models.Love.objects.create(b_id=1,g_id=1) # models.Love.objects.create(b_id=1,g_id=4) # models.Love.objects.create(b_id=2,g_id=4) # models.Love.objects.create(b_id=2,g_id=2)
# 1. 和方少偉有關係的姑娘 # obj = models.Boy.objects.filter(name='方少偉').first() # love_list = obj.love_set.all() # for row in love_list: # print(row.g.nick) # # # love_list = models.Love.objects.filter(b__name='方少偉') # for row in love_list: # print(row.g.nick) # # love_list = models.Love.objects.filter(b__name='方少偉').values('g__nick') # for item in love_list: # print(item['g__nick']) # # love_list = models.Love.objects.filter(b__name='方少偉').select_related('g') # for obj in love_list: # print(obj.g.nick)
第三章關係表 能夠本身定義類 或者使用內置的生成,可是隻能生成三列,二者合用 # m = models.ManyToManyField('Boy') 生成第三張關係表
#m = models.ManyToManyField('Girl',through="Love",through_fields=('b','g',)) 告訴django經過love鏈接,love表的b','g', 來關聯 只提供查詢和清空的功能
class Boy(models.Model): name = models.CharField(max_length=32) m = models.ManyToManyField('Girl',through="Love",through_fields=('b','g',))
class Girl(models.Model): nick = models.CharField(max_length=32) # m = models.ManyToManyField('Boy')
class Love(models.Model): b = models.ForeignKey('Boy') g = models.ForeignKey('Girl')#聯合惟一索引 class Meta: unique_together = [ ('b','g'), ]
# obj = models.Boy.objects.filter(name='方少偉').first() # print(obj.id,obj.name) # obj.m.add(2) # obj.m.add(2,4) # obj.m.add(*[1,])
# obj.m.remove(1) # obj.m.remove(2,3) # obj.m.remove(*[4,])
# obj.m.set([1,])
# q = obj.m.all() # # [Girl對象] # print(q) # obj = models.Boy.objects.filter(name='方少偉').first() # girl_list = obj.m.all()
# obj = models.Boy.objects.filter(name='方少偉').first() # girl_list = obj.m.all() # girl_list = obj.m.filter(nick='小魚') # print(girl_list)
# obj = models.Boy.objects.filter(name='方少偉').first() # obj.m.clear()
# obj = models.Girl.objects.filter(nick='小魚').first() # print(obj.id,obj.nick) # v = obj.boy_set.all() # print(v)
編寫ORM app01 -- models 中建立表ORM操做表:建立表修改表刪除表操做數據行:增刪改查ORM利用pymysql第三方工具鏈接數據庫默認:SQLliteMySQL:mysql -> MySQLDB(修改django默認鏈接mySQL方式)
XSS 跨站腳本攻擊 -慎用safe 和mark_safe(導入模塊 )from django.utils.safestring import mark_safe
safe 在html中代表
-非要用,必定要過濾關鍵字
csrf 通常post提交的時候驗證
FBv使用方法
a.基本應用 在form中添加 {% csrf_token %} {{ csrf_token }} 頁面會顯示隨機字符串信息
b. 全局禁用setting中 'django.middleware.csrf.CsrfViewMiddleware', 註釋
c. 局部禁用 全局使用,在函數上添加裝飾器 from django.views.decorators.csrf import csrf_exempt
@csrf_exemptdef index():passd.局部使用全局禁用 在函數上添加裝飾器
from django.views.decorators.csrf import csrf_protect
@csrf_protectdef index():pass
CBV使用裝飾器方法from django.views import Viewfrom django.utils.decorators import method_decorator
# 1. CBV應用裝飾器def wrapper(func): def inner(*args,**kwargs): return func(*args,**kwargs) return inner
# 1. 指定方法上添加裝飾器
# class Foo(View): # # @method_decorator(csrf_protect) # def get(self,request): # pass # # def post(self,request): # pass
# 2. 在類上添加# @method_decorator(csrf_protect,name='dispatch') #cbv中全部的提交都會先到dispatch # class Foo(View):## def get(self,request):# pass## def post(self,request):# pass
Ajax提交數據時候,攜帶CSRF:a. 放置在data中攜帶<form method="POST" action="/csrf1.html">{% csrf_token %}<input id="user" type="text" name="user" /><input type="submit" value="提交"/><a onclick="submitForm();">Ajax提交</a></form><script src="/static/jquery-1.12.4.js"></script><script>function submitForm(){var csrf = $('input[name="csrfmiddlewaretoken"]').val();var user = $('#user').val();$.ajax({url: '/csrf1.html',type: 'POST',data: { "user":user,'csrfmiddlewaretoken': csrf},success:function(arg){console.log(arg);}})}
</script>b. 放在請求頭中<form method="POST" action="/csrf1.html">{% csrf_token %}<input id="user" type="text" name="user" /><input type="submit" value="提交"/><a onclick="submitForm();">Ajax提交</a></form><script src="/static/jquery-1.12.4.js"></script><script src="/static/jquery.cookie.js"></script>
<script>function submitForm(){var token = $.cookie('csrftoken');var user = $('#user').val();$.ajax({url: '/csrf1.html',type: 'POST',headers:{'X-CSRFToken': token},data: { "user":user},success:function(arg){console.log(arg);}})}</script>
django視圖 cbv 、 fbv
CBV先dispatch 判斷method 反射若是想作定製化的 能夠添加在這裏
def dispatch(self, request, *args, **kwargs): print("before") obj=super(Login, self).dispatch(request,*args,**kwargs) print("after") return obj
url中設置re_path('classes/',views.Login.as_view),固定用法
view設置爲form表單只有post 和 get 方法,ajex 支持全部from django.views import Viewclass Login(View): ''' 請求方法基本經常使用的 get 查詢 post 建立 put 更新 delete 刪除 '''
def dispatch(self, request, *args, **kwargs): print("before") obj=super(Login, self).dispatch(request,*args,**kwargs) print("after") return obj
def get(self,request): pass
def put(self,request): pass
django 分頁操做分批獲取數據models.UserInfo.objects.all()[0:10]models.UserInfo.objects.all()[10:20]
---django 自帶提供的的分頁
from django.core.paginator import Paginator,Page,PageNotAnInteger,EmptyPage
def index(request): """ 分頁 :param request: :return: """ # for i in range(300): # name = "root" + str(i) # models.UserInfo.objects.create(name=name,age=18,ut_id=1)
current_page = request.GET.get('page')
user_list = models.UserInfo.objects.all() paginator = Paginator(user_list,10) # per_page: 每頁顯示條目數量 # count: 數據總個數 # num_pages:總頁數 # page_range:總頁數的索引範圍,如: (1,10),(1,200) # page: page對象 try: posts = paginator.page(current_page) except PageNotAnInteger as e: posts = paginator.page(1) except EmptyPage as e: posts = paginator.page(1) # has_next 是否有下一頁 # next_page_number 下一頁頁碼 # has_previous 是否有上一頁 # previous_page_number 上一頁頁碼 # object_list 分頁以後的數據列表 # number 當前頁 # paginator paginator對象 return render(request,'index.html',{'posts':posts})
--自定義分頁組件
from utils.pager import PageInfodef custom(request): # 表示用戶當前想要訪問的頁碼: 8
all_count = models.UserInfo.objects.all().count()
page_info = PageInfo(request.GET.get('page'),all_count,10,'/custom.html',11) user_list = models.UserInfo.objects.all()[page_info.start():page_info.end()]
return render(request,'custom.html',{'user_list':user_list,'page_info':page_info})
class PageInfo(object):
def __init__(self,current_page,all_count,per_page,base_url,show_page=11): """
:param current_page: :param all_count: 數據庫總行數 :param per_page: 每頁顯示函數 :return: """ try: self.current_page = int(current_page) except Exception as e: self.current_page = 1 self.per_page = per_page
a,b = divmod(all_count,per_page) if b: a = a +1 self.all_pager = a self.show_page = show_page self.base_url = base_url def start(self): return (self.current_page-1) * self.per_page
def end(self): return self.current_page * self.per_page
def pager(self): # v = "<a href='/custom.html?page=1'>1</a><a href='/custom.html?page=2'>2</a>" # return v page_list = []
half = int((self.show_page-1)/2)
# 若是數據總頁數 < 11 if self.all_pager < self.show_page: begin = 1 stop = self.all_pager + 1 # 若是數據總頁數 > 11 else: # 若是當前頁 <=5,永遠顯示1,11 if self.current_page <= half: begin = 1 stop = self.show_page + 1 else: if self.current_page + half > self.all_pager: begin = self.all_pager - self.show_page + 1 stop = self.all_pager + 1 else: begin = self.current_page - half stop = self.current_page + half + 1
if self.current_page <= 1: prev = "<li><a href='#'>上一頁</a></li>" else: prev = "<li><a href='%s?page=%s'>上一頁</a></li>" %(self.base_url,self.current_page-1,) page_list.append(prev)
for i in range(begin,stop): if i == self.current_page: temp = "<li class='active'><a href='%s?page=%s'>%s</a></li>" %(self.base_url,i,i,) else: temp = "<li><a href='%s?page=%s'>%s</a></li>" %(self.base_url,i,i,) page_list.append(temp)
if self.current_page >= self.all_pager: nex = "<li><a href='#'>下一頁</a></li>" else: nex = "<li><a href='%s?page=%s'>下一頁</a></li>" %(self.base_url,self.current_page+1,) page_list.append(nex)
return ''.join(page_list)
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title></title> <link rel="stylesheet" href="/static/plugins/bootstrap-3.3.7-dist/css/bootstrap.css" /></head><body> <h1>用戶列表</h1> <ul> {% for row in user_list %} <li>{{ row.name }}</li> {% endfor %} </ul>
<nav aria-label="Page navigation"> <ul class="pagination"> {{ page_info.pager|safe }} </ul> </nav></body></html>css