Luffy專案
一、Luffy專案需求(2)
1、後臺日誌封裝
需求:
在專案目錄下建立logs目錄,用於記錄專案日誌
要求:
- 列印在控制檯
- 記錄在logs檔案下的日誌檔案中
- 所有專案日誌統一管理
操作步驟:
- 第一步:在專案配置檔案中進行配置-----大字典
# 詳情在下方大字典中檢視
- 第二步:在utils檔案下新建common_logger.py得到日誌物件
import logging
logger = logging.getLogger('django')
- 第三步:在需要使用的地方直接匯入使用
from utils.common_logger import logger
logger.info('info級別的日誌')
logger.error('error級別的日誌')
配置字典:
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'formatters': {
'verbose': {
'format': '%(levelname)s %(asctime)s %(module)s %(lineno)d %(message)s'
},
'simple': {
'format': '%(levelname)s %(module)s %(lineno)d %(message)s'
},
},
'filters': {
'require_debug_true': {
'()': 'django.utils.log.RequireDebugTrue',
},
},
'handlers': {
'console': {
# 實際開發建議使用WARNING
'level': 'INFO',
'filters': ['require_debug_true'],
'class': 'logging.StreamHandler',
'formatter': 'simple'
},
'file': {
# 實際開發建議使用ERROR
'level': 'WARNING',
'class': 'logging.handlers.RotatingFileHandler',
# 日誌位置,日誌檔名,日誌儲存目錄必須手動建立,注:這裡的檔案路徑要注意BASE_DIR代表的是小luffyapi
'filename': os.path.join(os.path.dirname(BASE_DIR), "logs", "luffy.log"),
# 日誌檔案的最大值,這裡我們設定300M
'maxBytes': 300 * 1024 * 1024,
# 日誌檔案的數量,設定最大日誌數量為10
'backupCount': 10,
# 日誌格式:詳細格式
'formatter': 'verbose',
# 檔案內容編碼
'encoding': 'utf-8'
},
},
# 日誌物件
'loggers': {
'django': {
'handlers': ['console', 'file'],
'propagate': True, # 是否讓日誌資訊繼續冒泡給其他的日誌處理系統
},
}
}
2、全域性異常處理、封裝
需求:
當使用者在使用專案的時候,可能會出現報錯,如果不對報錯進行處理,那麼專案將會直接崩潰,針對這個問題應該對錯誤進行捕獲,並返回統一的錯誤資訊給使用者,提高使用者體驗
要求:
本次專案使用的是drf框架,
- 對drf和專案的報錯資訊統一格式反饋給使用者
操作步驟:
- 第一步:在utils檔案下建立common_excepions.py
- 第二步:編寫函式
詳見下方程式碼
- 第四步:在專案配置檔案中進行配置
REST_FRAMEWORK = {
'EXCEPTION_HANDLER': 'utils.common_exceptions.exception_handler',
}
函式程式碼:
from rest_framework.views import exception_handler as drf_exception_handler
from utils.common_logger import logger
from rest_framework.response import Response
def exception_handler(exc, context):
# 獲取request
request = context.get('request')
# 獲取登入使用者
user = request.user
if not user:
user = '匿名使用者'
# 獲取使用者ip
user_ip = request.META.get('REMOTE_ADDR')
# 獲取出錯的檢視函式
view = context.get('view')
# 獲取路由地址
url_path = request.get_full_path()
# response(有:drf錯誤/無:專案錯誤)
response = drf_exception_handler(exc, context)
if response:
# 將錯誤資訊記錄
logger.warning('異常來源:【drf】,異常資訊:【%s】' % str(exc))
# 將錯誤資訊進行處理返回給前端
res = Response({'code': 998, 'msg': request.data.get('detail', '系統異常,請聯絡管理員')})
else:
# 記錄錯誤資訊
logger.error('錯誤來源:【系統內部】,使用者:【%s】,ip地址:【%s】,訪問地址:【%s】,執行檢視函式:【%s】,錯誤詳情:【%s】'
% (user, user_ip, url_path, str(view), str(exc)))
# 統一處理錯誤資訊
res = Response({'code': 999, 'msg': '系統異常,請聯絡管理員'})
return res
3、封裝Response物件
需求:
在後期編寫檢視函式需要將介面資訊返回給前端時,每次都需要反覆的編寫介面資訊,很多資料都是重複的,封裝新的responce,重複的介面資訊不需要反覆編寫
要求:
封裝新的response物件
- 反饋資料時,不需要反覆的編寫code、msg類的資料
# 本身drf有Response,但是我們們公司規定,前端收到的格式都是固定的
-{code:100,msg:提示,data:{}/[]}
-{code:100,msg:提示,token:asdfasd,user:lqz}
# 對Response進行封裝,封裝後,code,msg可以不傳,不傳就用預設的
操作步驟:
- 第一步:在uitls檔案下新建common_response.py
- 第二步:封裝新的response物件(APIresponse)
詳細程式碼如下
- 第三步:需要反饋資料時,只需要返回自己封裝的物件
函式程式碼:
from rest_framework.response import Response
class ApiResponse(Response):
def __init__(self, code=100, msg='成功', status=None, headers=None, **kwargs):
data = {'code': code, 'msg': msg}
if kwargs:
data.update(**kwargs)
super().__init__(data=data, status=status, headers=headers)
二、Luffy專案資料庫建立
1、建立使用者資料庫
# 建立luffy資料庫
# 之前專案運算元據庫,都是使用root使用者,root使用者許可權太高了,在公司裡,一般不會給你root使用者許可權
# 如果開發人員是root許可權,資料安全性就很差
# 開發人員,專門建立一個使用者,使用者只對當前專案的庫有操作許可權
# 建立一個luffy庫,建立luffy使用者,luffy使用者只對luffy庫有操作許可權
"""
1.管理員連線資料庫
>: mysql -uroot -proot
2.建立資料庫
>: create database luffy default charset=utf8;
3.檢視使用者
>: select user,host from mysql.user;
只有root使用者,要建立luffy使用者
# 5.7往後的版本
>: select user,host,authentication_string from mysql.user;
"""
#建立路飛使用者,授予luffy庫所有許可權
"""
設定許可權賬號密碼
# 授權賬號命令:grant 許可權(create, update) on 庫.表 to '賬號'@'host' identified by '密碼'
1.配置任意ip都可以連入資料庫的賬戶
>: grant all privileges on luffy.* to 'luffy'@'%' identified by 'Luffy123?';
2.由於資料庫版本的問題,可能本地還連線不上,就給本地使用者單獨配置
>: grant all privileges on luffy.* to 'luffy'@'localhost' identified by 'Luffy123?';
3.重新整理一下許可權
>: flush privileges;
只能操作luffy資料庫的賬戶
賬號:luffy
密碼:Luffy123?
"""
2、使用專案連結資料庫
前置條件:
# 專案操作mysql,需要安裝模組
-pymysql
-mysqlDB
-mysqlclient
-歷史:原來py2上有個操作mysql的模組叫mysqlDB,但到py3,沒有支援py3,django預設使用這個模組去連線mysql,預設使用-mysqlDB連線,-mysqlDB不支援py3,執行報錯
-我們使用pymysql,作為連線mysql的資料庫模組,但是需要加程式碼
imprort pymysql
pymysql.install_as_mysqldb() # 猴子補丁
-django 2.2.2以後,還使用pymysql,需要改djagno原始碼
-統一使用mysqlclient來作為操作mysql的底層庫
-基於py2的mysqldb,在py3上重新了,但是名字改成了mysqlclient
-使用mysqlclient,只需要安裝這個模組,不需要再寫任何程式碼,直接用即可
-但是:mysqlclient 這個模組,不好裝
-win 一般人品好,人品好,pip install mysqlclient
-人品不好,裝不了,centos部署專案,後面會講centos上如何裝
# mysqlclient
pip install mysqlclient
###### 配置檔案修改,連線mysql,使用路飛使用者
# 使用者名稱密碼寫死在程式碼中了,保證安全
name = os.environ.get('LUFFY_NAME', 'luffy')
password = os.environ.get('LUFFY_PASSWORD', 'Luffy123?')
# 擴充:有的公司,直接有個配置中心---》服務--》只用來存放配置檔案
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'luffy',
'USER': name,
'PASSWORD': password,
'HOST': '127.0.0.1',
'PORT': 3306
}
}
2、User模組使用者表
注意事項:
# 你決定使用auth表擴寫,專案一定不要先遷移,先建好使用者表再遷移
已經遷移完了,再想用auth的user表
-刪庫,刪遷移檔案所有app
-刪admin和auth的遷移檔案
操作程式碼:
# 配置繼承auth表
AUTH_USER_MODEL = 'user.User'
# 使用者表使用auth表擴寫 pip install Pillow
class User(AbstractUser):
# 擴寫手機號和頭像欄位
mobile = models.CharField(max_length=11, unique=True)
# 需要pillow包的支援
icon = models.ImageField(upload_to='icon', default='icon/default.png')
class Meta:
db_table = 'luffy_user'
verbose_name = '使用者表'
verbose_name_plural = verbose_name
def __str__(self):
return self.username
3、開啟media訪問
配置檔案:
# 配置檔案加入
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
路由設定:
from django.contrib import admin
from django.urls import path, re_path
from django.views.static import serve
from django.conf import settings
urlpatterns = [
path('admin/', admin.site.urls),
# media路由
path('media/<path:path>', serve, {'document_root': settings.MEDIA_ROOT}),
# re_path(r'^media/(?P<path>.*)$', serve, {'document_root': settings.MEDIA_ROOT}),
]
三、軟體開發模式
介紹:
在對於一個優秀的軟體開發團隊來說,有效的管理開發專案,可以增強開發人員之間的協作,節省整個軟體專案的開發時間,因此軟體開發經理或開發團隊在專案啟動前,要選擇一種最適合手頭專案的軟體開發模式,使整個團隊擁有更好的工作效率,而目前主要的軟體開發模式大致可以分為四種,對於軟體專案來講不同的開發模式都有各自的特點,至於哪一種的方法最合適自己,那就要看軟體開發經理如何選擇了。
1、瀑布開發模式
瀑布開發模式是一種傳統的軟體開發模式,瀑布法是一個剛性的線性模型,其中包括順序階段(需求,設計,實施,驗證,維護),其中每一個階段的目標性都很明確。而且在進入下一階段之前,每個階段目標必須100%地完成,但這種模式如果進行回溯修改時會比較麻煩。
但該方法的線性特性使其易於理解和管理。如果軟體專案對穩定要求比較高,那可以選擇這種開發模式。在使用瀑布開發模式時豐富的軟體開發經驗會比較有幫助。然而,由於剛性結構和嚴格的控制特點,通常會導致專案的開發時間比較慢、成本比較昂貴。
2、敏捷開發模式
敏捷開發模式有許多不同的形式,包括:Scrum,Crystal,Extreme Programming(XP)和Feature-Driven Development(FDD)。它透過迭代開發,關注互動溝通等方法來降低軟體開發過程中的風險,同時也可以減少在開發中的資源消耗。好處是透過早期發現和修復缺陷來提高開發的效率。但這種模式比較依賴使用者的資訊反饋,而且這種模式比較適用於小規模的軟體開發公司,習慣於“瀑布法”的程式設計師,管理層和組織可能難以適應敏捷。
3、快速應用開發模式
快速應用開發模式是一個比較精簡的軟體開發流程,可以以低投資成本生產高質量的軟體。這種RAD流程可以使開發人員快速適應不斷變化的市場需求。快速調整的能力可以幫助企業節省開發成本。快速應用程式開發模式分為四個階段:需求規劃,使用者設計,構建和切換。重複使用者設計和施工階段,直到滿足使用者的所有要求。
RAD對於具有明確定義的業務目標及使用者組的開發專案最有效,比較適用於一些中小型軟體開發專案,或者是開發時間比較緊迫的軟體專案。然而,它需要技術人員具有豐富開發經驗,以及要非常瞭解使用者的核心需求。
4、DevOps部署模式
DevOps部署模式增強了軟體開發部門之間的協作,如開發,測試和運營。它著重於改進軟體的上市時間,降低新版本的故障率,縮短BUG修復的交付時間,優先考慮最小的中斷以及最大的可靠性等。
使用DevOps部署模式對提高客戶滿意度,提高產品質量,提高員工的生產力和效率得益(Efficiency Gain)等方面非常有用。但DevOps也有一些缺點:
有些客戶不想持續更新他們的軟體
一些行業在允許進入運營階段之前,需要進行大量測試
不同部門使用的不同環境可能導致軟體開發過程中一些問題不會顯現出來
一些質量屬性需要人為的相互作用,這會減慢軟體的交付流程
四、Django配置檔案介紹
from pathlib import Path
import sys
import os
# pathlib # 3.6 以後,處理檔案路徑的模組,原來是os,
BASE_DIR = Path(__file__).resolve().parent.parent
sys.path.append(os.path.join(BASE_DIR, 'apps'))
sys.path.insert(0, BASE_DIR)
# 專案金鑰
SECRET_KEY = 'django-insecure-@3=-v&bd_o4hxy4)*v^r0y5d=27cg73)awt9zm1+v$2)$!kj6b'
# 開發模式,上線需要關閉
DEBUG = True
# 設定可以訪問該伺服器的地址 一般填入“*”
ALLOWED_HOSTS = []
# 註冊app
INSTALLED_APPS = [
'django.contrib.admin', # django-admin
'django.contrib.auth', # django的auth模組
'django.contrib.contenttypes', # 存放表關係
'django.contrib.sessions', # sessions表
'django.contrib.messages', # messages:訊息框架,flask講閃現,是一樣的東西
'django.contrib.staticfiles', # staticfiles:靜態資源
'rest_framework',
'home',
'user'
]
# 中介軟體註冊的地方
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware', # 安全相關中介軟體
'django.contrib.sessions.middleware.SessionMiddleware', # session相關中介軟體
'django.middleware.common.CommonMiddleware', # 處理路由帶不帶 / 問題
'django.middleware.csrf.CsrfViewMiddleware', # csrf 認證,生成csrf串
'django.contrib.auth.middleware.AuthenticationMiddleware', # 使用者認證
'django.contrib.messages.middleware.MessageMiddleware', # 訊息框架相關
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
# 總路由的存放地址
ROOT_URLCONF = 'luffy_api.urls'
# 模板檔案(前後端分離用不到)
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [BASE_DIR / 'templates']
,
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
# 專案執行的配置---》專案上線執行,使用uwsgi 執行 application()
WSGI_APPLICATION = 'luffy_api.wsgi.application'
# 資料庫相關,可填入多個資料庫
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'db.sqlite3',
}
}
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
# 國際化相關配置
LANGUAGE_CODE = 'zh-hans'
TIME_ZONE = 'Asia/Shanghai'
USE_I18N = True
USE_TZ = False
# 靜態資源
STATIC_URL = 'static/'
# 修改了主鍵的欄位屬性(新版本)
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'