2020-05-27 Django小結(jié)

  1. Web應(yīng)用
    --- HTTP 請求 --->
    瀏覽器 服務(wù)器
    <--- HTTP 響應(yīng) ---

    靜態(tài)內(nèi)容:HTML頁面、CSS、JavaScript、圖像拆魏、音視頻等 ---> Nginx
    動態(tài)內(nèi)容:需要通過程序自動生成的部分 ---> Python ---> 運行Python程序的服務(wù)器

    HTTP(s) ---> 超文本傳輸協(xié)議 ---> 使用了TCP提供的可靠傳輸服務(wù)

    HTTP請求:請求行 / 請求頭 / 空行 / 消息體
    HTTP響應(yīng):響應(yīng)行 / 響應(yīng)頭 / 空行 / 消息體

  2. 為什么用Python做后端開發(fā)?
    ~ 自動化運維 / 自動化測試 / 數(shù)據(jù)分析 / AI算法 / DevOps / SRE
    ~ 服務(wù)器端應(yīng)用開發(fā)(Web后端開發(fā))
    ---> App/網(wǎng)站的服務(wù)端代碼編寫(數(shù)據(jù)接口開發(fā))
    ---> 用代碼生成網(wǎng)站/App需要的動態(tài)內(nèi)容(數(shù)據(jù))
    ---> CGI / WSGI ---> PHP / ASP(C#) / JSP(Java)
    ~ Python也可以為作為服務(wù)器端應(yīng)用開發(fā)的編程語言
    ~ 優(yōu)點:開發(fā)效率極高(用很少的代碼可以做很多的事情)
    ~ 缺點:執(zhí)行效率不高(有很多公司更看重開發(fā)效率而不是執(zhí)行效率)
    ~ Python有很多的框架專門用于服務(wù)器端應(yīng)用開發(fā)
    ---> 使用框架可以減少重復(fù)代碼和基礎(chǔ)代碼的編寫
    ---> 程序員只需要專注于核心的業(yè)務(wù)邏輯代碼的編寫

  3. 為什么選擇Django框架?
    ---> 源于真實的CMS系統(tǒng)的項目
    ---> 生態(tài)圈非常繁榮 ---> 大部分功能都有成熟的解決方案

  4. 創(chuàng)建Django項目和實施版本控制
    ~ pip3 install django==2.2.12 -i https://pypi.doubanio.com/simple
    ~ django-admin --version
    ~ django-admin startproject hellodjango
    ~ cd hellodjango

    創(chuàng)建虛擬環(huán)境
    ~ 方法一:virtualenv --python=/usr/bin/python3 venv
    ~ 方法二:python3 -m venv venv

    激活虛擬環(huán)境
    ~ source venv/bin/activate ---> macOS / Linux
    ~ "venv/Scripts/activate" ---> Windows

    重建項目依賴項:
    ~ 有依賴項清單:pip install -r requirements.txt
    ~ 如果沒有依賴項清單:
    - pip install django==2.2.12 mysqlclient django-redis requests
    - pip freeze > requirements.txt

    ~ git init
    ~ 根據(jù)需要添加版本控制忽略文件 ---> .gitginore ---> http://gitignore.io/
    ~ git add .
    ~ git commit -m '...'
    ~ Gitee上創(chuàng)建一個空的倉庫
    ~ git remote add origin 倉庫地址
    ~ git push -u origin master

  5. 創(chuàng)建Django應(yīng)用
    ~ 一個Django項目中可以包含一個或多個Django應(yīng)用
    - 方法一:django-admin startapp 應(yīng)用名
    - 方法二:python manage.py startapp 應(yīng)用名
    ~ settings.py ---> INSTALLED_APPS ---> 應(yīng)用名

補充:Django框架使用了MTV架構(gòu)模式 ---> MVC架構(gòu) ---> 數(shù)據(jù)和顯示分離
同一組數(shù)據(jù)(模型)可以展示為不同的視圖(HTML表格嘹害、ECharts圖表、Excel報表)
同一個視圖上也可以加載不同的模型進行渲染
M -----> 模型(數(shù)據(jù))-----> M
V -----> 視圖(數(shù)據(jù)的展示吮便,呈現(xiàn)給用戶看到的東西)-----> T
C -----> 控制器(連接數(shù)據(jù)和顯示的橋梁笔呀,把模型和視圖關(guān)聯(lián)起來)-----> V
~ view.py ----> 視圖函數(shù) ----> 控制器
~ models.py ----> 模型
~ templates ----> 模板 ----> 視圖

  1. 編寫視圖函數(shù)
    ~ views.py ---> 視圖函數(shù)(接收來自瀏覽器的請求,給用戶以響應(yīng))

    def show_index(request: HttpRequest):

     return HttpResponse(content)
    
  2. 配置URL
    ~ 使用視圖函數(shù)需要配置URL映射(請求的路由) ---> urls.py
    ~ URL(統(tǒng)一資源定位符) ---> 視圖函數(shù) ---> path函數(shù)

    path('hello/', show_index),
    path('mcode/<str:tel>/', get_mobile_code),

    url(r'^mcode/(?P<tel>1[3-9]\d{9})/')

    def get_mobile_code(request, tel):
    pass

  3. 前端渲染和后端渲染
    ~ 真正的項目開發(fā)中髓需,前端工程師會提供靜態(tài)頁面许师,如何讓靜態(tài)頁面上呈現(xiàn)動態(tài)內(nèi)容?僚匆?微渠?
    ~ 方法一:前端渲染 ---> 在瀏覽器中完成渲染操作
    前端通過Ajax請求獲得后端提供的數(shù)據(jù),通過JavaScript代碼用數(shù)據(jù)渲染頁面
    ~ 方法二:后端渲染 ---> 在服務(wù)器端用Python程序完成
    把前端提供的靜態(tài)頁改造成模板頁咧擂,把動態(tài)內(nèi)容換成占位符逞盆,通過Python程序把動態(tài)內(nèi)容填入模板頁

  4. 編寫、配置松申、渲染模板頁
    <ul id="fruits">
    {% for fruit in fruits %}
    <li>{{ fruit.name }}: {{ fruit.price }}<a href="">×</a></li>
    {% endfor %}
    </ul>

    TEMPLATES = [
    {
    'BACKEND': 'django.template.backends.django.DjangoTemplates',
    'DIRS': [os.path.join(BASE_DIR, 'templates'), ],
    'APP_DIRS': True,
    ...
    },
    ]

    render(request, 'index.html', {...}) ---> HttpResponse

  5. 運行Django項目
    ~ Django自帶的測試服務(wù)器 ---> 不能用于生產(chǎn)環(huán)境
    ~ python manage.py runserver

    Web Server Gateway Interface
    Nginx / Apache --- wsgi ---> 實現(xiàn)了WSGI的服務(wù)器
    支持WSGI協(xié)議的服務(wù)器就可以運行Python項目
    ~ uWSGI / Gunicorn

  6. Django框架中內(nèi)置了ORM功能
    ~ ORM:對象關(guān)系映射 Object-Relational Mapping
    Python程序 ----------------------> 關(guān)系型數(shù)據(jù)庫
    對象模型 -----對象持久化到數(shù)據(jù)庫-----> 關(guān)系模型
    對象模型 <----從數(shù)據(jù)庫中獲取數(shù)據(jù)------ 關(guān)系模型
    class Subject(models.Model):
    ~ AutoField / IntegerField / DecimalField / DateTimeField
    ~ CharField / ImageField / FileField / BooleanField
    ~ OneToOneField / ForeignKey / ManyToManyField
    ~ 新增:Subject(...).save()
    ~ 查詢:Subject.objects.all() / Subject.objects.filter() ---> QuerySet
    ~ 查詢:Subject.objects.get() / Subject.objects.filter().first() ---> Subject
    ~ 排序:order_by()
    ~ 分頁:[:] ---> Paginator ---> get_page() ---> Page
    ~ objects_list / has_prev / has_next / number
    ~ 分組和聚合:annotate() / aggregate()
    ~ 多條件組合篩選:Q對象
    - Q & Q / Q | Q / ~Q
    ~ 更新:subject ---> subject.name = '...' ---> subject.save()
    - F對象:queryset ---> update(字段=F('字段名') + 100)
    ~ 刪除:subject ---> subject.delete()

  7. Django模型管理后臺
    ~ python manage.py createsuperuser
    ~ 將模型注冊到管理后臺 ---> admin.py
    admin.site.register(模型, 模型管理類)

    django-jet

  8. 返回JSON格式數(shù)據(jù)
    JavaScript Object Notation ---> JavaScript創(chuàng)建對象的字面量語法 ---> 數(shù)據(jù)交換格式
    Python字典 ---> JSON字符串
    ujson ---> ultra json ---> C
    ~ 方法一:ujson.dumps(字典) ---> JSON字符串 ---> HttpResponse ---> application/json
    ~ 方法二:JsonResponse(字典) ---> JSON格式數(shù)據(jù)

  9. 從請求中獲取信息
    HttpRequest
    ~ 獲取請求參數(shù):GET / POST / FILES / data
    ~ 獲取請求路徑: path / get_full_path_info()
    ~ 獲取請求方法:method
    ~ 獲取請求頭:META / COOKIES
    ~ 判斷是不是異步請求:is_ajax()
    ~ 獲取帶簽名的cookie:get_signed_cookie()
    HttpResponse
    ~ 響應(yīng)狀態(tài)碼:status_code
    ~ 響應(yīng)字符集:charset
    ~ 響應(yīng)頭:
    - response['content-type']
    - response['content-disposition']
    ~ set_cookie() / delete_cookie() / set_signed_cookie()

    用戶跟蹤:記住用戶才能提供更好的更個性化的服務(wù) ---> 瀏覽器本地存儲
    ~ cookie
    ~ localStorage / sessionStorage
    ~ IndexDB

  10. 表單和跨站請求偽造
    CSRF ---> Cross Site Request Forgery ---> 跨站請求偽造/釣魚網(wǎng)站

    Django框架通過在表單添加隨機令牌的方式來解決CSRF問題
    {% csrf_token %}
    <input type="hidden" name="csrfmiddlewaretoken" value="...">
    如果沒有提供有效的隨機令牌云芦,Django框架會阻止表單提交,響應(yīng)狀態(tài)碼403

    @csrf_exempt ---> 視圖函數(shù)免除CSRF令牌的裝飾器

  11. 數(shù)據(jù)庫決不能放用戶密碼的原始數(shù)據(jù) ---> 摘要/簽名/指紋
    hashlib ---> md5 / sha1 / sha256
    sha256() ---> update(...) ---> hexdigest()
    彩虹表攻擊 ---> 反向查字典破解弱口令
    如果你的網(wǎng)站允許用戶使用弱口令攻臀,那么一定要通過加鹽的方式把弱口令變成強口令再生成摘要
    鹽的值只有部署系統(tǒng)的管理員才知道(程序員和DBA都不知道)

  12. 服務(wù)器如何保留用戶狀態(tài) ---> 用戶跟蹤
    服務(wù)器如果能記住用戶焕数,記住用戶的使用偏好,就能夠更好的為用戶提供服務(wù)
    request.session ---> 保存在服務(wù)端的一個類似于字典的對象
    瀏覽器同時還是用了本地存儲技術(shù) ---> cookie ---> 用戶身份信息(sessionid)
    ---> HTTP請求頭會攜帶本網(wǎng)站的cookie信息 ---> sessionid --->
    和用戶關(guān)聯(lián)的那個session對象 ---> 獲取之前保存在session中的數(shù)據(jù) ---> 用戶跟蹤

    瀏覽器實現(xiàn)本地存儲有多種方案:
    ~ cookie(使用起來最簡單刨啸,瀏覽器兼容性最好)
    ~ localStorage / sessionStorage
    ~ IndexDB

    request.session['...'] = ...

    python manage.py clearsessions

  13. Django項目接入Redis實現(xiàn)緩存服務(wù)
    memcached ---> Redis ---> Django接入Redis
    pip install django-redis

    CACHES = {
    'default': {
    'BACKEND': 'django_redis.cache.RedisCache',
    'LOCATION': 'redis://主機:端口/0',
    'OPTIONS': {
    'CLIENT_CLASS': 'django_redis.client.DefaultClient',
    'PASSWORD': 'Redis口令'
    }
    }
    }

    SESSION_ENGINE = 'django.contrib.sessions.backends.cache'
    SESSION_CACHE_ALIAS = 'default'

  14. 導(dǎo)出Excel文件
    Office 2010 ---> Excel 2010 ---> openpyxl
    Office 2003 ---> Excel 2003 ---> xlwt / xlrd

    Workbook ---> sheet ---> sheet['A1'] ---> save()
    BytesIO --- getvalue() ---> bytes ---> HttpResponse
    ~ content-type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
    ~ content-disposition: inline / attachment; filename=...

  15. 生成統(tǒng)計圖表
    前端接入ECharts ---> 通過JavaScript實現(xiàn)圖表效果渲染
    后端提供JSON數(shù)據(jù) ---> JsonResponse

  16. 原生SQL查詢
    django.db.transaction.get_connection() ---> Connection對象
    ---> cursor() ---> execute() ---> fetchone() / fetchmany() / fetchall()

  17. 中間件(攔截過濾器)
    def simple_middleware(get_response):

    def middleware(request, *args, **kwargs):
    
        response = get_response(request)
    
        return response
    
    return middleware
    

    Django中間件與之前學(xué)過的裝飾器在寫法和用途上都非常接近堡赔,
    通過Django項目配置文件的MIDDLEWARE可以配置使用中間件

  18. 調(diào)用三方服務(wù)(你自己無法完成的功能)
    ~ SDK集成 --->
    - pip install alipay-python-sdk
    - pip install qiniu
    ~ API調(diào)用 ---> URL統(tǒng)一資源定位符 ---> HTTP ---> JSON
    - pip install requests
    request.get(url) / requests.post(url, data={...})

  19. ORM框架調(diào)優(yōu)
    ~ 限制查詢字段:only / defer
    ~ 解決1+N查詢:select_related / prefetch_related
    ~ Q對象 / F對象

  20. Django-Debug-Toolbar
    INSTALLED_APPS ---> 'debug_toolbar'

    MIDDLEWARE ---> 'debug_toolbar.middleware.DebugToolbarMiddleware'

    DEBUG_TOOLBAR_CONFIG = {
    # 引入jQuery庫
    'JQUERY_URL': 'https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js',
    # 工具欄是否折疊
    'SHOW_COLLAPSED': True,
    # 是否顯示工具欄
    'SHOW_TOOLBAR_CALLBACK': lambda x: True,
    }

    if settings.DEBUG:
    import debug_toolbar
    urlpatterns.insert(0, path('debug/', include(debug_toolbar.urls)))

  1. 日志配置
    ~ 級別:DEBUG < INFO < WARNING < ERROR < CRITICAL

    LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    # 配置日志格式化器
    'formatters': {
    'simple': {
    'format': '%(asctime)s %(module)s.%(funcName)s: %(message)s',
    'datefmt': '%Y-%m-%d %H:%M:%S',
    },
    'verbose': {
    'format': '%(asctime)s %(levelname)s [%(process)d-%(threadName)s] '
    '%(module)s.%(funcName)s line %(lineno)d: %(message)s',
    'datefmt': '%Y-%m-%d %H:%M:%S',
    }
    },
    # 配置日志過濾器
    'filters': {
    'require_debug_true': {
    '()': 'django.utils.log.RequireDebugTrue',
    },
    },
    # 配置日志處理器
    'handlers': {
    'console': {
    'class': 'logging.StreamHandler',
    'level': 'DEBUG',
    'filters': ['require_debug_true'],
    'formatter': 'simple',
    },
    'file1': {
    'class': 'logging.handlers.TimedRotatingFileHandler',
    'filename': 'access.log',
    'when': 'W0',
    'backupCount': 12,
    'formatter': 'simple',
    'level': 'INFO',
    },
    'file2': {
    'class': 'logging.handlers.TimedRotatingFileHandler',
    'filename': 'error.log',
    'when': 'D',
    'backupCount': 31,
    'formatter': 'verbose',
    'level': 'WARNING',
    },
    },
    # 配置日志器
    'loggers': {
    'django': {
    'handlers': ['console', 'file1', 'file2'],
    'propagate': True,
    'level': 'DEBUG',
    },
    }
    }

  2. 其他知識點
    ~ DTL:Django模板語法
    模板指令:
    - {% if %} / {% else %} / {% endif %}
    - {% for %} / {% endfor %}
    過濾器:
    - lower / upper / first / last / truncatewords / date/ time
    / length / pluralize / center / ljust / rjust / cut / urlencode
    / default_if_none / filesizeformat / join / slice / slugify

    ~ 路徑參數(shù)
    - Django 1.x:url(r'mcode/(?P<mobile>1[3-9]\d{9})')
    - Django 2.x:path('mcode/<str:mobile>')

    ~ base64編碼:用64個可讀文本符號表示任意二進制數(shù)據(jù)
    base64.b64encode / base64.b64decode

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市设联,隨后出現(xiàn)的幾起案子善已,更是在濱河造成了極大的恐慌灼捂,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,372評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件换团,死亡現(xiàn)場離奇詭異悉稠,居然都是意外死亡,警方通過查閱死者的電腦和手機艘包,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評論 3 392
  • 文/潘曉璐 我一進店門的猛,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人想虎,你說我怎么就攤上這事卦尊。” “怎么了舌厨?”我有些...
    開封第一講書人閱讀 162,415評論 0 353
  • 文/不壞的土叔 我叫張陵岂却,是天一觀的道長。 經(jīng)常有香客問我裙椭,道長躏哩,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,157評論 1 292
  • 正文 為了忘掉前任揉燃,我火速辦了婚禮扫尺,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘你雌。我一直安慰自己器联,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,171評論 6 388
  • 文/花漫 我一把揭開白布婿崭。 她就那樣靜靜地躺著,像睡著了一般肴颊。 火紅的嫁衣襯著肌膚如雪氓栈。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,125評論 1 297
  • 那天婿着,我揣著相機與錄音授瘦,去河邊找鬼。 笑死竟宋,一個胖子當(dāng)著我的面吹牛提完,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播丘侠,決...
    沈念sama閱讀 40,028評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼徒欣,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了蜗字?” 一聲冷哼從身側(cè)響起打肝,我...
    開封第一講書人閱讀 38,887評論 0 274
  • 序言:老撾萬榮一對情侶失蹤脂新,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后粗梭,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體争便,經(jīng)...
    沈念sama閱讀 45,310評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,533評論 2 332
  • 正文 我和宋清朗相戀三年断医,在試婚紗的時候發(fā)現(xiàn)自己被綠了滞乙。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,690評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡鉴嗤,死狀恐怖斩启,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情躬窜,我是刑警寧澤浇垦,帶...
    沈念sama閱讀 35,411評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站荣挨,受9級特大地震影響男韧,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜默垄,卻給世界環(huán)境...
    茶點故事閱讀 41,004評論 3 325
  • 文/蒙蒙 一此虑、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧口锭,春花似錦朦前、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至荆隘,卻和暖如春恩伺,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背椰拒。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評論 1 268
  • 我被黑心中介騙來泰國打工晶渠, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人燃观。 一個月前我還...
    沈念sama閱讀 47,693評論 2 368
  • 正文 我出身青樓褒脯,卻偏偏與公主長得像,于是被迫代替她去往敵國和親缆毁。 傳聞我的和親對象是個殘疾皇子番川,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,577評論 2 353