內容回顧: 1. django請求生命週期 -> 執行遵循wsgi協議的模塊(socket服務端) -> 中間件(路由匹配) -> 視圖函數(業務處理:ORM、模板渲染) -> 中間件 -> wsgi返回 2. 什麼wsgi web服務網關接口 實現該協議的模塊: - wsgiref - werkzurg - uwsig 3. 視圖 - FBV url - 函數 - CBV url - view 4. djang rest framework 5. restful 規範(10) 什麼是接口? - URL - 約束 # 約束繼承(實現)了他的類中必須含有IFoo中的方法 interface IFoo: def func(self): pass class Foo(IFoo): def func(self): print(11111) 1. 根據method不一樣,進行不一樣操做 GET/POST/PUT/DELETE/PATCH 2. 面向資源編程 http://www.luffycity.com/salary 3. 體現版本 http://www.luffycity.com/v1/salary http://www.luffycity.com/v2/salary https://v4.bootcss.com/ https://v3.bootcss.com/ 4. 體現是API http://www.luffycity.com/api/v1/salary http://www.luffycity.com/api/v2/salary http://api.luffycity.com/v1/salary http://api.luffycity.com/v2/salary 5. https https://www.luffycity.com/api/v1/salary https://www.luffycity.com/api/v2/salary 6. 響應式設置狀態碼 200 300 400 500 return HttpResponse('adfasdf',status=300) 7. 條件 https://www.luffycity.com/api/v2/salary?page=1&size=10 8. 返回值 https://www.luffycity.com/api/v2/salary GET: 全部列表 { code: 10000, data: [ {'id':1,'title':'高亮'}, {'id':1,'title':'龍泰'}, {'id':1,'title':'小東北'}, ] } POST: 返回新增的數據 {'id':1,'title':'高亮'} https://www.luffycity.com/api/v2/salary/1/ GET: 獲取單條數據 {'id':1,'title':'高亮'} PUT:更新 {'id':1,'title':'高亮'} PATCH: 局部更新 {'id':1,'title':'高亮'} DELETE:刪除 9. 返回錯誤信息 { code: 100001, error: 'xxx錯誤' } 10. Hypermedia API ret = { code: 1000, data:{ id:1, name:'小強', depart_id:http://www.luffycity.com/api/v1/depart/8/ } } 建議你們使用restful規範 6. django rest framework框架(10) - 權限 - 認證 - 訪問頻率限制 - 序列化 - 路由 - 視圖 面試題:你的寫的類都繼承過哪些類? class View(object): class APIView(View): class GenericAPIView(views.APIView): class GenericViewSet(ViewSetMixin, generics.GenericAPIView) class ModelViewSet(mixins.CreateModelMixin, mixins.RetrieveModelMixin, mixins.UpdateModelMixin, mixins.DestroyModelMixin, mixins.ListModelMixin, GenericViewSet): - 分頁 - 解析器 - 渲染器 - 版本 今日內容: - vue - restful api 內容詳細: 1. 渲染器 規定頁面顯示的效果(無用) 2. 版本 原理:要了解 使用: 1. 添加配置 REST_FRAMEWORK = { .... 'DEFAULT_VERSIONING_CLASS':'rest_framework.versioning.URLPathVersioning', 'ALLOWED_VERSIONS':['v1','v2'], # 容許的版本 'VERSION_PARAM':'version', # 參數 'DEFAULT_VERSION':'v1', # 默認版本 .... } 2. 設置路由 s9luffycity/urls.py urlpatterns = [ #url(r'^admin/', admin.site.urls), url(r'^api/(?P<version>\w+)/', include('api.urls')), ] api/urls.py urlpatterns = [ url(r'^course/$', course.CourseView.as_view()), ] 3. 獲取版本 request.version 獲取版本 3. vue+rest framework vue: - 路由 + 組件 - axios發送ajax請求 - that api: - 跨域 補充: - 域名不一樣 - 端口不一樣 cors: 本質設置響應頭 # 容許你的域名來獲取個人數據 response['Access-Control-Allow-Origin'] = "*" # 容許你攜帶Content-Type請求頭 response['Access-Control-Allow-Headers'] = "Content-Type" # 容許你發送DELETE,PUT response['Access-Control-Allow-Methods'] = "DELETE,PUT" 做業: 1.建立兩張表 課程表: id title 1 Python全棧 2 Python週末 3 Linux 課程詳細表: id name course_id 1 Python基礎 1 2 Python進階 1 3 Python網絡 1 4 Python併發 1 5 Python數據庫 1 6 Python前端 1 2. 兩個頁面 - 課程列表 - 課程詳細
內容回顧: - restful 規範(10) - django rest framework框架(10) - 跨域 - 爲何會有跨域? - 繞過瀏覽器同源策略就能夠跨域。 - jsonp 動態建立script標籤 同源策略會阻止ajax請求;不阻止具備src屬性的標籤 <script src='xxxx'></script> - cors 設置響應頭 今日內容: - vue - api 內容詳細: 1. vue - 課程列表 - 課程詳細 - 任務: - 課程表 id title course_img level(choices) - 課程詳細(one2one 課程 ) id why 推薦課程 - 章節 id name - 功能: a. 課程列表顯示圖片 b. 課程詳細顯示: - 爲何要學習這個課程 - 全部推薦課程 - 全部章節 2. api 1. 查詢全部的課程 http://127.0.0.1:8000/api/v1/course/ 練習:level變中文 2. 查詢課程詳細 http://127.0.0.1:8000/api/v1/course/1/ - 路由 as_view 是否添加參數,取決於視圖繼承的類 - 序列化 - depth - source - 自定義method 練習:顯示該課程相關的全部章節 this補充: 題目1: var name = '景女神' function Foo(name,age){ this.name = name; this.age = age; this.getName = function(){ console.log(this.name); # 文州 (function(){ console.log(this.name); # 女神 })() } } obj = new Foo('文州',19) obj.getName() 題目2: var name = '景女神' function Foo(name,age){ this.name = name; this.age = age; this.getName = function(){ console.log(this.name); # 文州 var that = this (function(){ console.log(that.name); # 文州 })() } } obj = new Foo('文州',19) obj.getName() 題目3: var name = '景女神' obj = { name:'文州', age: 19, getName:function(){ console.log(this.name); # 文州 var that = this (function(){ console.log(that.name); # 文州 })() } } obj.getName() 做業: 1. 先後端流程 2. 圖片 3. CC視頻帳號 4. git相關 - 安裝git軟件 - 註冊github帳號
內容回顧: 1. 你理解的Http協議? - 創建在tcp之上 - 一次請求一次響應而後斷開鏈接(無狀態、短鏈接) - 請求和響應 發送:請求頭\r\n\r\n請求體 host:www.luffy.com\r\ncontent-type:application/json\r\n\r\n請求體 響應:響應頭\r\n\r\n響應體 ... 2. django請求生命週期 3. wsgi 4. django中間件是什麼? 5. 使用中間件作過什麼? - 內置 - csrf - session - 自定義 - 登陸認證 - 權限 - cors 6. 中間件中有多少個方法? 5個 7. FBV和CBV是什麼?以及優缺點。 8. rest api 9. django rest framework框架 10. 視圖常見的繼承 from rest_framework.views import APIView # * from rest_framework.generics import GenericAPIView from rest_framework.viewsets import GenericViewSet # as_view from rest_framework.viewsets import ModelViewSet # * 11. 如何實現的訪問頻率控制? 匿名用戶:沒法控制,由於用戶能夠換代理IP { 192.168.1.1:[1521223123.232, 1521223122.232, 1521223121.232], 192.168.1.2:[1521223123.232, 1521223122.232, 1521223121.232], 192.168.1.3:[1521223123.232, 1521223122.232, 1521223121.232], 192.168.1.4:[1521223123.232, 1521223122.232, 1521223121.232], 192.168.1.5:[1521223123.232, 1521223122.232, 1521223121.232], 192.168.1.6:[1521223123.232, 1521223122.232, 1521223121.232], } 登陸用戶:若是有不少帳號,也沒法限制 { alex:[1521223123.232, 1521223122.232, 1521223121.232], eric:[1521223123.232, 1521223122.232, 1521223121.232], } 參考源碼:from rest_framework.throttling import SimpleRateThrottle 12. 序列化 - source - method 今日內容: 1. 示例 - 推薦課程 - 用戶登陸 - 攔截器 VUE: - 課程列表:this.$axios + this - 課程詳細:this.$axios + this - 用戶登陸: - this.$axios - this - 跨域簡單和複雜請求 - vuex作全局變量 - vuex-cookies - 微職位 - 攔截器 - 攜帶token PS: api能夠同一放在store中保存 API: - 課程列表 - 序列化:source='get_level_display' - 課程詳細: - 序列化:source='get_level_display' - 序列化:method - 用戶登陸 - update_or_create - 微職位 - 認證組件 關聯組件: - 版本 - 解析器 - 渲染器 - 序列化 - 認證組件 - 視圖 - 路由 2. django組件:contenttype 組件的做用:能夠經過兩個字段讓表和N張表建立FK關係 表結構: from django.db import models from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.fields import GenericForeignKey, GenericRelation class DegreeCourse(models.Model): """學位課程""" name = models.CharField(max_length=128, unique=True) course_img = models.CharField(max_length=255, verbose_name="縮略圖") brief = models.TextField(verbose_name="學位課程簡介", ) class Course(models.Model): """專題課程""" name = models.CharField(max_length=128, unique=True) course_img = models.CharField(max_length=255) # 不會在數據庫生成列,只用於幫助你進行查詢 policy_list = GenericRelation("PricePolicy") class PricePolicy(models.Model): """價格與有課程效期表""" content_type = models.ForeignKey(ContentType) # 關聯course or degree_course object_id = models.PositiveIntegerField() #不會在數據庫生成列,只用於幫助你進行添加和查詢 content_object = GenericForeignKey('content_type', 'object_id') valid_period_choices = ( (1, '1天'), (3, '3天'), (7, '1周'), (14, '2周'), (30, '1個月'), (60, '2個月'), (90, '3個月'), (180, '6個月'), (210, '12個月'), (540, '18個月'), (720, '24個月'), ) valid_period = models.SmallIntegerField(choices=valid_period_choices) price = models.FloatField() 使用: # 1.在價格策略表中添加一條數據 # models.PricePolicy.objects.create( # valid_period=7, # price=6.6, # content_type=ContentType.objects.get(model='course'), # object_id=1 # ) # models.PricePolicy.objects.create( # valid_period=14, # price=9.9, # content_object=models.Course.objects.get(id=1) # ) # 2. 根據某個價格策略對象,找到他對應的表和數據,如:管理課程名稱 # price = models.PricePolicy.objects.get(id=2) # print(price.content_object.name) # 自動幫你找到 # 3.找到某個課程關聯的全部價格策略 # obj = models.Course.objects.get(id=1) # for item in obj.policy_list.all(): # print(item.id,item.valid_period,item.price) # 3. 表結構
內容回顧: 1. 爲何會有跨域? 瀏覽器具備同源策略全部纔出現跨域。 同源策略: - 開放:src - 禁止:ajax 解決跨域: - jsonp,在客戶端動態建立一個script標籤 1.客戶端:建立一個 <script src='http://www.jxntv.cn/data/jmd-jxtv2.html'></script> <script> function func(arg){ alert(arg); } </script> 2.服務端:接收到請求並處理並返回值 "func('success')" 至關於: <script> func('success') </script> PS: jsonp只能發送GET請求 - cors,設置響應響應響應響應響應頭 - 簡單請求 - 複雜請求 - options請求作預檢 - PUT/POST.... 在django中解決方案: - 中間件中設置響應頭 - django中的一個第三方組件:cors 補充: jQuery Ajax: $.ajax({ ... }) 原生Ajax:XMLHttpRequest對象: var xhr = new XMLHttpRequest() xhr.onreadystatechange = function(){ if(xhr.readyState == 4){ // 已經接收到所有響應數據,執行如下操做 var data = xhr.responseText; console.log(data); } }; xhr.open('POST', "/test/", true); // 設置請求頭 xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset-UTF-8'); // 發送請求 xhr.send('n1=1;n2=2;'); 2. restful 規範 3. 你理解的http協議? 4. 常見請求頭 - Content-Type - User-Agent - referer,能夠作圖片防盜鏈。 - Host - cookies 5. 常見的請求方法: - GET/POST/DELETE/PUT/PATCH/OPTIONS 6. 常見的狀態碼: - 200 - 301/302 - 403/404 - 500 7. 序列化 8. ORM補充: a. 需求: 只取某n列 queryset=[ {},{}] models.User.objects.all().values( 'id','name') queryset=[ (),()] models.User.objects.all().values_list( 'id','name') queryset=[ obj,obj] result = models.User.objects.all().only('id','name','age') # result = models.User.objects.all().defer('id','name','age') for item in reuslt: print(item.id,item.name,item.age) b. 需求: 打印全部用戶姓名以及部門名稱 class depart: title = .... class User: name = ... dp = FK(depart) # select * from user # result = models.User.objects.all() # for item in result: # print(item.name) # select * from user left join depart on user.dp_id = depart.id # result = models.User.objects.all().selected_related('dp') # for item in result: #print(item.name,item.dp.title ) 今日內容: 1. 路飛學城表結構 - 課程 - 深科技 2. 支付寶支付 內容詳細: 1. 路飛學城表結構 - 課程 - 學位課(導師、獎學金、分模塊、週期) - 專題課 (小柯,週期) - 深科技 2. 支付寶支付 a. 去支付寶申請 - 正式:營業執照 - 測試:沙箱測試環境 APPID:2016082500309412 買家: nbjsag5718@sandbox.com 111111 111111 b. 開發程序 SDK - 官方 - github pay.py 依賴:pip3 install pycryptodome 公鑰私鑰: - 應用公鑰 - 支付寶公鑰 - 應用私鑰
內容回顧: 1. Http協議? Http協議就是一個傳輸數據格式。 我原來學習django框架,從socket服務端開始學起。 本身創造了一個socket服務器來充當:網站。 瀏覽器當socket客戶端。 更清楚的明白到底http協議是什麼? - 請求頭 請求頭 - 響應頭 響應頭 一次請求響應後,斷開鏈接。 2. 常見請求頭 3. 常見的請求體? Form表單提交: POST /index http1.1\r\nhost:www.luffycity.com...\r\n\r\nusername=alex&password=123&... Ajax請求: POST /index http1.1\r\nhost:www.luffycity.com...\r\n\r\nusername=alex&password=123&... POST /index http1.1\r\nhost:www.luffycity.com...\r\n\r\n{「username」:"alex","password":123} 補充:django中獲取請求體 - request.POST - request.body 4. django請求生命週期 - wsgi, 他就是socket服務端,用於接收用戶請求並將請求進行初次封裝,而後將請求交給web框架(Flask、Django) - 中間件,幫助咱們對請求進行校驗或在請求對象中添加其餘相關數據,例如:csrf、request.session - 路由匹配 - 視圖函數,在視圖函數中進行業務邏輯的處理,可能涉及到:orm、templates => 渲染 - 中間件,對響應的數據進行處理。 - wsgi,將響應的內容發送給瀏覽器。 5. 中間件 - 5個方法 - 應用場景: - 登陸認證,再也不須要在每一個函數中添加裝飾器 - 權限,當用戶登陸時候獲取當前用戶全部權限並放入session,而後再次訪問其餘頁面,獲取當前url並在session中進行匹配。若是沒有匹配成功,則在中間件返回「無權訪問」 - 跨域, - jsonp,動態建立一個script標籤。 - cors,設置響應頭 應用:本地開始先後端分離的時使用。 6. ORM操做 - only - defer - seleted_related - prefetch_related 示例: class Depart(models.Model): 5個部門 title = models.CharField(...) class User(models.Model): 10個用戶 name = models.CharField(...) email = models.CharField(...) dp = models.FK(Depart) 1.之前的你:11次單表查詢 result = User.objects.all() for item in result: print(item.name,item.dp.title) 2. seleted_related,主動作連表查詢(1次鏈表) result = User.objects.all().seleted_related('dp') for item in result: print(item.name,item.dp.title) 問題:若是鏈表多,性能愈來愈差。 3. prefetch_related:2次單表查詢 # select * from user ; # 經過python代碼獲取:dp_id = [1,2] # select * from depart where id in dp_id result = User.objects.all().prefetch_related('dp') for item in result: print(item.name,item.dp.title) 贈送: 數據量比較大,不會使用FK,容許出現數據冗餘。 7. django rest framework的做用? 快速搭建基於restful規範的接口。 8. 你理解的 restful 規範? restful是一個規範,規定API如何編寫,經過他可讓咱們api更加簡潔可維護。 如,最直觀的: method: - get - post - put - delete 原來都是url中設置的。 除此以外: - api - 版本 - 名詞 - 條件 - 狀態碼 - 返回值 - 錯誤信息 - hypermedia link 9. django rest framework組件: - 訪問頻率控制原理: 匿名: 1.1.1.1:[時間,時間,時間,時間,] 登陸: user:[時間,時間,時間,時間,] 默認將訪問記錄放在緩存中:redis/memcached - 序列化 from rest_framework.serializers import Serializer class XX(Serializer): pass ser =XX(queryset,many=True) # ListSerializer對象 ser =XX(obj, many=False) # XX對象 - 列表生成式 - 根據字符串的形式,自動導入模塊並使用反射找到模塊中的類【參考:s9day108】。 今日內容: 1. 深科技表結構 2. git 內容詳細: 1. 深科技表結構(6表) # ######################## 深科技相關 ######################## class ArticleSource(models.Model): """文章來源""" name = models.CharField(max_length=64, unique=True) class Meta: verbose_name_plural = "16. 文章來源" def __str__(self): return self.name class Article(models.Model): """文章資訊""" title = models.CharField(max_length=255, unique=True, db_index=True, verbose_name="標題") source = models.ForeignKey("ArticleSource", verbose_name="來源") article_type_choices = ((0, '資訊'), (1, '視頻')) article_type = models.SmallIntegerField(choices=article_type_choices, default=0) brief = models.TextField(max_length=512, verbose_name="摘要") head_img = models.CharField(max_length=255) content = models.TextField(verbose_name="文章正文") pub_date = models.DateTimeField(verbose_name="上架日期") offline_date = models.DateTimeField(verbose_name="下架日期") status_choices = ((0, '在線'), (1, '下線')) status = models.SmallIntegerField(choices=status_choices, default=0, verbose_name="狀態") order = models.SmallIntegerField(default=0, verbose_name="權重", help_text="文章想置頂,能夠把數字調大,不要超過1000") vid = models.CharField(max_length=128, verbose_name="視頻VID", help_text="文章類型是視頻, 則須要添加視頻VID", blank=True, null=True) comment_num = models.SmallIntegerField(default=0, verbose_name="評論數") agree_num = models.SmallIntegerField(default=0, verbose_name="點贊數") view_num = models.SmallIntegerField(default=0, verbose_name="觀看數") collect_num = models.SmallIntegerField(default=0, verbose_name="收藏數") # tags = models.ManyToManyField("Tags", blank=True, verbose_name="標籤") date = models.DateTimeField(auto_now_add=True, verbose_name="建立日期") position_choices = ((0, '信息流'), (1, 'banner大圖'), (2, 'banner小圖')) position = models.SmallIntegerField(choices=position_choices, default=0, verbose_name="位置") #comment = GenericRelation("Comment") class Meta: verbose_name_plural = "17. 文章" def __str__(self): return "%s-%s" % (self.source, self.title) class Collection(models.Model): """收藏""" content_type = models.ForeignKey(ContentType) object_id = models.PositiveIntegerField() content_object = GenericForeignKey('content_type', 'object_id') account = models.ForeignKey("Account") date = models.DateTimeField(auto_now_add=True) class Meta: unique_together = ('content_type', 'object_id', 'account') verbose_name_plural = "18. 通用收藏表" class Comment(models.Model): """通用的評論表""" content_type = models.ForeignKey(ContentType, blank=True, null=True, verbose_name="類型") object_id = models.PositiveIntegerField(blank=True, null=True) content_object = GenericForeignKey('content_type', 'object_id') p_node = models.ForeignKey("self", blank=True, null=True, verbose_name="父級評論") content = models.TextField(max_length=1024) account = models.ForeignKey("Account", verbose_name="會員名") disagree_number = models.IntegerField(default=0, verbose_name="踩") agree_number = models.IntegerField(default=0, verbose_name="贊同數") date = models.DateTimeField(auto_now_add=True) def __str__(self): return self.content class Meta: verbose_name_plural = "19. 通用評論表" class Account(models.Model): username = models.CharField("用戶名", max_length=64, unique=True) password = models.CharField("密碼", max_length=64) class UserAuthToken(models.Model): """ 用戶Token表 """ user = models.OneToOneField(to="Account") token = models.CharField(max_length=64, unique=True) 2. git git是一個用於幫助用戶實現版本控制的軟件。 命令: git init git status 查看當前文件夾的狀態。 git add 文件名 對指定文件進行版本控制 git add . 對指定文件夾下的全部文件及子目錄進行版本控制 git commit -m '詳細的描述信息' 建立提交記錄(版本) git log git reflog git reset --hard 提交記錄(版本號)