本周是第十周,本周學習了django框架前后端分離相關知識點,REST框架,網(wǎng)絡API接口,以及性能調(diào)試,以下是知識點回顧與整理:
1.11本周總結
-
版本控制補充 - 回退
- git reset --hard versionid / head^
- git reflog 記錄
-
django日志配置 - settings.py
日志級別:DEBUG < INFO < WARNING < ERROR < CRITICAL
ELK - ElasticSearch Logstash Kibana - 日志處理平臺
# settings.py,以下配置為日志debug級別打印至控制臺 LOGGING = { 'version': 1, 'disable_existing_loggers': False, 'handlers': { 'console': { 'level': 'DEBUG', 'class': 'logging.StreamHandler', }, }, 'loggers': { 'django.db': { 'handlers': ['console', ], 'level': 'DEBUG', }, }, }?
-
django-debug-toolbar - django調(diào)試工具
debug-debug-toolbar可查看數(shù)據(jù)請求的時長、數(shù)據(jù)庫查詢語句等
配置:settings.py與urls.py
# 首先安裝第三方庫:pip install django-debug-toolbar # settings.py 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, } # urls.py from django.conf import settings from django.urls import include if settings.DEBUG: import debug_toolbar urlpatterns.insert(0, path('__debug__/', include(debug_toolbar.urls))) -
性能優(yōu)化之一,數(shù)據(jù)庫1+N查詢問題,是指只需只需用SQL語句查詢一次即可出結果,卻重復查詢多次
方法:利用django的連表查詢
? - 一對多:select_related()
? - 多對多:prefetch_related()
-
django項目前后端分離開發(fā)
- 服務器完成核心業(yè)務返回json等數(shù)據(jù),客服端處理渲染數(shù)據(jù)與頁面
- 優(yōu)點:
- 提升開發(fā)效率
- 增強代碼可維護性
- 支持多終端和服務器結構
-
API - Application Programming Interface 應用程序編程接口
網(wǎng)絡API - 通過http/https請求請求一個url獲得json數(shù)據(jù)
API接口應圍繞實體設計,而不是圍繞業(yè)務設計,否則后期更改會增加工作量與復雜度
實體 -- 數(shù)據(jù) -- 數(shù)據(jù)接口 -- 網(wǎng)絡API(基于http/https)
REST架構 - RESTful API -- 無狀態(tài)、冪等性
? - 冪等性:一次貨多次請求某一個資源對于資源本身具有同樣的結果
? REST - REpresentational State Transfer - 表現(xiàn)層狀態(tài)轉移
? rest可以更好的支持水平擴展 - 單機結構 --> 多機結構(分布式集群)
http -- 無連接無狀態(tài)協(xié)議
url -- universal resource locator 統(tǒng)一資源定位符,根據(jù)rest架構url設計應使用名詞
get -- 查看
post -- 新增
put -- 全更新
patch -- 補丁似的更新
delete -- 刪除
-
具體網(wǎng)絡API接口項目如下,以房源信息獲取為例:
- 首先對rest框架進行安裝配置
# rest框架的安裝 - pip install djangorestframework # settings.py INSTALLED_APPS = [ ... 'rest_framework', ]- 其次,序列化房源信息
? fields表示需要獲取的數(shù)據(jù),'__all__'表示獲取全部數(shù)據(jù),exclude表示排除的數(shù)據(jù)
# 序列化器,在app文件夾下創(chuàng)建一個serializers.py存放序列化內(nèi)容,對需要的數(shù)據(jù)進行序列化 # serializers.py from rest_framework import serializers from common.models import District, Estate, Agent, HouseType, HouseInfo class HouseInfoSerializer(serializers.ModelSerializer): class Meta: model = HouseInfo fields = '__all__' # exclude = ('houseid',)- CBV視圖創(chuàng)建
# view.py from rest_framework.viewsets import ReadOnlyModelViewSet from common.models import HouseInfo from common.serializers import HouseInfoSerializer # CBV基于類的視圖創(chuàng)建 class HouseInfoViewSet(ReadOnlyModelViewSet): queryset = HouseInfo.objects.all().select_related('type', 'district', 'estate', 'agent').prefetch_related('tags').order_by('-pubdate') serializer_class = HouseInfoSerializer- urls.py配置,在app文件夾內(nèi) 創(chuàng)建一個新的urls.py配置文件,作為單獨的配置
# urls.py from django.urls import path from rest_framework.routers import SimpleRouter from common.views import HouseInfoViewSet # 創(chuàng)建一個房源信息的路由 router = SimpleRouter() router.register('houseinfo', HouseInfoViewSet) urlpatterns += router.urls這時房源的全部信息API接口已經(jīng)完成,進入http://127.0.0.1:8000/api/houseinfo/ 可獲取房源的全部信息
-
設置全局分頁查看房源信息,并且限制查詢次數(shù)每分鐘5次
# DRF配置文件 REST_FRAMEWORK = { # 按頁碼分頁 'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination', 'PAGE_SIZE': 5, # 每頁最大顯示5條數(shù)據(jù) # 限流配置 'DEFAULT_THROTTLE_CLASSES': ( 'rest_framework.throttling.AnonRateThrottle', ), 'DEFAULT_THROTTLE_RATES': { 'anon': '5/min', # 一分鐘訪問5次 }, } -
設置redis緩存,對部分長期不變的信息進行緩存,可減輕數(shù)據(jù)庫負擔,提高查詢速度,從而提高用戶體驗
# settings.py # rest緩存配置 REST_FRAMEWORK_EXTENSIONS = { 'DEFAULT_CACHE_RESPONSE_TIMEOUT': 120, # 過期時間 'DEFAULT_USE_CACHE': 'default', 'DEFAULT_OBJECT_CACHE_KEY_FUNC': 'rest_framework_extensions.utils.default_object_cache_key_func', 'DEFAULT_LIST_CACHE_KEY_FUNC': 'rest_framework_extensions.utils.default_list_cache_key_func', } # redis緩存配置 CACHES = { 'default': { 'BACKEND': 'django_redis.cache.RedisCache', 'LOCATION': [ 'redis://ip address/0', ], 'KEY_PREFIX': 'projcet_name', 'OPTIONS': { 'CLIENT_CLASS': 'django_redis.client.DefaultClient', 'CONNECTION_POOL_KWARGS': { 'max_connections': 512, }, 'PASSWORD': 'your password', } }, }- 在app文件夾下創(chuàng)建一個utils.py的文件,用于存放app的功能函數(shù)等
# utils.py # 對redis存儲的緩存前綴進行修改 import re PATTERN = re.compile(r'(\.[0-9a-f]{32})') def make_key(key, key_prefix, version): items = PATTERN.findall(key)[1:] for item in items: key = key.replace(item, '') return '%s:%s:%s' % (key_prefix, version, key)?
- 在view.py中添加裝飾器,對需要緩存的數(shù)據(jù)添加裝飾器
# view.py class HouseInfoViewSet(CacheResponseMixin,ModelViewSet): ... -
添加篩選器,對關鍵字進行篩選,或者對價格進行排序,篩選價格區(qū)間等等
# utils.py # 自定義filterset過濾器篩選功能 class HouseInfoFilterSet(django_filters.FilterSet): """自定義FilterSet過濾""" minprice = django_filters.NumberFilter(field_name='price', lookup_expr='gte') maxprice = django_filters.NumberFilter(field_name='price', lookup_expr='lte') keyword = django_filters.CharFilter(method='filter_by_keyword') @staticmethod def filter_by_keyword(queryset, key, value): queryset = queryset.filter(Q(title__contains=value) | Q(detail__contains=value) | Q(street__contains=value)) return queryset- 其次在views.py文件,房源信息視圖類中添加如下內(nèi)容
# views.py from django_filters.rest_framework import DjangoFilterBackend from rest_framework.filters import OrderingFilter from common.utils import HouseInfoFilterSet class HouseInfoViewSet(ModelViewSet): ... filter_backends = (DjangoFilterBackend, OrderingFilter) filterset_class = HouseInfoFilterSet ordering_fields = ('price', 'area', 'floor') # 排序內(nèi)容?
?