-
版本控制補(bǔ)充 - 回退(rollback)相當(dāng)于在git上提交代碼后,再對之前提交的代碼的版本進(jìn)行回溯。這個(gè)過程中,全程都會被log記錄進(jìn)行記錄。所以在回退的時(shí)候,查看版本的代碼ID就變得尤為重要了,因?yàn)槲覀兓赝说囊罁?jù)就是這個(gè)id。
- git reset --hard versionid / head^
- git reflog 記錄
-
django日志配置 - settings.py ---注意:在這個(gè)日志配置的過程中,會有兩種不同的操作。當(dāng)然如果“我都想要”也是可以行的。兩種分別是:在控制臺輸出日志的內(nèi)容和在重定向的文件中查看具體的日志內(nèi)容。日志的級別多種多樣,并且不同的級別會對應(yīng)著不同的詳細(xì)程度的日志內(nèi)容。這個(gè)可以在以下的表單中找到具體有哪些級別(詳細(xì)程度):
日志級別: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)試工具
說明:
這個(gè)工具是對django框架的調(diào)試進(jìn)行的一個(gè)集成化工具。我們可以使用這個(gè)工具查看到很多信息。在以下的說明中,我們會使用該工具對數(shù)據(jù)庫那邊查詢的sql指令進(jìn)行查看。往往未經(jīng)優(yōu)化的sql語句查詢都是特別糟糕的。例如產(chǎn)生一加N查詢,這樣的多個(gè)sql查詢語句或許會成為整個(gè)系統(tǒng)運(yùn)行的性能瓶頸。為了優(yōu)化這一點(diǎn),我們會通過不同的辦法來優(yōu)化sql語句,即用工具查看到的如下語句,然后提高了數(shù)據(jù)庫的查詢速度,整個(gè)系統(tǒng)也會得到優(yōu)化。這是木桶效應(yīng)的一個(gè)明顯展示。
debug-debug-toolbar可查看數(shù)據(jù)請求的時(shí)長、數(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語句查詢一次即可出結(jié)果,卻重復(fù)查詢多次
為了解決這樣的1+N查詢,我們會用簡單的兩行代碼加入連表查詢使得幾次不同的查詢匯集成同一個(gè)查詢。這個(gè)樣子的inner join的查詢會大大提高數(shù)據(jù)庫的工作效率。
方法:利用django的連表查詢
? - 一對多:select_related()
? - 多對多:prefetch_related()
-
django項(xiàng)目前后端分離開發(fā)
說明:django的前后端開發(fā)在之前的總結(jié)中已經(jīng)有過提及。但是之前的框架是“用django框架自動生成數(shù)據(jù)庫表。并且在html中自己寫下前端代碼?!边@樣的開發(fā)是不科學(xué)也是不專業(yè)的。在真正的前后端分離的開發(fā)中,數(shù)據(jù)后端是提供業(yè)務(wù)邏輯和具體數(shù)據(jù)庫的增刪改查的操作的業(yè)務(wù)流程的,而前端是將接受到的端口數(shù)據(jù)進(jìn)行進(jìn)一步渲染處理的工作。
- 服務(wù)器完成核心業(yè)務(wù)返回json等數(shù)據(jù),客服端處理渲染數(shù)據(jù)與頁面
- 優(yōu)點(diǎn):
- 提升開發(fā)效率
- 增強(qiáng)代碼可維護(hù)性
- 支持多終端和服務(wù)器結(jié)構(gòu)
-
API - Application Programming Interface 應(yīng)用程序編程接口
說明:應(yīng)用程序的編程接口又稱API,在具體的開發(fā)過程中,后端會給前端一個(gè)應(yīng)用程序的編程接口來提供業(yè)務(wù)邏輯和數(shù)據(jù)庫的代碼響應(yīng)支持。
網(wǎng)絡(luò)API - 通過http/https請求請求一個(gè)url獲得json數(shù)據(jù)
API接口應(yīng)圍繞實(shí)體設(shè)計(jì),而不是圍繞業(yè)務(wù)設(shè)計(jì),否則后期更改會增加工作量與復(fù)雜度
實(shí)體 -- 數(shù)據(jù) -- 數(shù)據(jù)接口 -- 網(wǎng)絡(luò)API(基于http/https)
REST架構(gòu) - RESTful API -- 無狀態(tài)、冪等性
? - 冪等性:一次貨多次請求某一個(gè)資源對于資源本身具有同樣的結(jié)果
? REST - REpresentational State Transfer - 表現(xiàn)層狀態(tài)轉(zhuǎn)移
? rest可以更好的支持水平擴(kuò)展 - 單機(jī)結(jié)構(gòu) --> 多機(jī)結(jié)構(gòu)(分布式集群)
http -- 無連接無狀態(tài)協(xié)議
url -- universal resource locator 統(tǒng)一資源定位符,根據(jù)rest架構(gòu)url設(shè)計(jì)應(yīng)使用名詞
get -- 查看
post -- 新增
put -- 全更新
patch -- 補(bǔ)丁似的更新
delete -- 刪除
-
具體網(wǎng)絡(luò)API接口項(xiàng)目如下,以房源信息獲取為例:
說明:具體的接口項(xiàng)目下文將按照房源信息的獲取作為一個(gè)例子,為大家展示一下具體的案例:
- 首先對rest框架進(jìn)行安裝配置
# rest框架的安裝 - pip install djangorestframework # settings.py INSTALLED_APPS = [ ... 'rest_framework', ]- 其次,序列化房源信息
? fields表示需要獲取的數(shù)據(jù),'__all__'表示獲取全部數(shù)據(jù),exclude表示排除的數(shù)據(jù)
# 序列化器,在app文件夾下創(chuàng)建一個(gè)serializers.py存放序列化內(nèi)容,對需要的數(shù)據(jù)進(jìn)行序列化 # 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 ModelViewSet from common.models import HouseInfo from common.serializers import HouseInfoSerializer # CBV基于類的視圖創(chuàng)建 class HouseInfoViewSet(ModelViewSet): queryset = HouseInfo.objects.all() serializer_class = HouseInfoSerializer- urls.py配置,在app文件夾內(nèi) 創(chuàng)建一個(gè)新的urls.py配置文件,作為單獨(dú)的配置
# urls.py from django.urls import path from rest_framework.routers import SimpleRouter from common.views import HouseInfoViewSet # 創(chuàng)建一個(gè)房源信息的路由 router = SimpleRouter() router.register('houseinfo', HouseInfoViewSet) urlpatterns += router.urls這時(shí)房源的全部信息API接口已經(jīng)完成,進(jìn)入http://127.0.0.1:8000/api/houseinfo/ 可獲取房源的全部信息
-
設(shè)置全局分頁查看房源信息,并且限制查詢次數(shù)每分鐘5次
說明:對查詢次數(shù)的限流是有助于網(wǎng)站維護(hù)穩(wěn)定的操作。因?yàn)楫?dāng)服務(wù)器的http請求到達(dá)一個(gè)閾值的時(shí)候,整個(gè)服務(wù)器的訪問速度會明顯下降。而具體的數(shù)學(xué)模型請參照清華大學(xué)數(shù)據(jù)研究員的數(shù)據(jù)。因此我們在次數(shù)首先對單個(gè)用戶的訪問做出了一定的限制:即在合理的范圍內(nèi)的請求可以發(fā)出并且得以應(yīng)答,在超出我們設(shè)置的每分鐘五次之后的數(shù)據(jù)不予發(fā)出。
# 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次 }, } -
設(shè)置redis緩存,對部分長期不變的信息進(jìn)行緩存,可減輕數(shù)據(jù)庫負(fù)擔(dān),提高查詢速度,從而提高用戶體驗(yàn)
說明:redis是一個(gè)著名的菲關(guān)系型數(shù)據(jù)庫。用以緩存我們接收到的各種數(shù)據(jù)。因此我們使用這個(gè)數(shù)據(jù)庫來作為緩存,將可能多次復(fù)用且短時(shí)間不發(fā)生改變的數(shù)據(jù)使用redis進(jìn)行數(shù)據(jù)緩存。這樣也可以大大提高整個(gè)系統(tǒng)的訪問效率。
# settings.py # rest緩存配置 REST_FRAMEWORK_EXTENSIONS = { 'DEFAULT_CACHE_RESPONSE_TIMEOUT': 120, # 過期時(shí)間 '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)建一個(gè)utils.py的文件,用于存放app的功能函數(shù)等
# utils.py # 對redis存儲的緩存前綴進(jìn)行修改 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ù)添加裝飾器
```python
# view.py
from django.utils.decorators import method_decorator
from django.views.decorators.cache import cache_page
@method_decorator(decorator=cache_page(timeout=300, key_prefix='houseinfo:list'), name='list')
@method_decorator(decorator=cache_page(timeout=300, key_prefix='houseinfo:retrieve'), name='retrieve')
class HouseInfoViewSet(ModelViewSet):
...
- 添加篩選器,對關(guān)鍵字進(jìn)行篩選,或者對價(jià)格進(jìn)行排序,篩選價(jià)格區(qū)間等等
說明:篩選器就是對整個(gè)數(shù)據(jù)列表或者說是更準(zhǔn)確的查詢集進(jìn)行數(shù)據(jù)篩選。對于想要的數(shù)據(jù),我們可以通過添加filterset來進(jìn)行數(shù)據(jù)過濾篩選。在這個(gè)篩選器中,我們可以自定義過濾器的篩選算法,以達(dá)到想要怎樣的數(shù)據(jù),就返還用戶什么樣的數(shù)據(jù)的效果。
# 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)容
?
?