使用django框架進行web項目開發須要瞭解的知識

1.虛擬環境的搭建

因爲在每一個項目所使用的解析器,當你運行別人的項目或者和別人合做開發一個項目,各個模塊的版本存在差別,建立虛擬環境可讓你運行的環境與別人的保持一致,html

虛擬環境的搭建在linue系統和window系統存在細微的差異前端

linux系統

建立虛擬環境:  mkvirtualenv  虛擬環境名python

指定解析器器的版本: mkvirtualenv luffy -p python3(這個是指定python解析器使用python3,能夠根據需求寫本身項目版本)linux

查看全部虛擬環境:workonredis

使用虛擬環境:workon  虛擬環境名稱數據庫

推出虛擬環境: deactivatedjango

刪除虛擬環境: rmvirtualenv 虛擬環境名稱(不能刪除當前正在使用的虛擬環境,須要先退出再刪除)後端

若是當前系統中沒有mkvirtualenv命令,可使用sudo apt-get install python-virtualenv和sudo easy_install virtualenvwrapper來安裝api

window系統

安裝virtualenv:pip install virtualenv服務器

建立虛擬環境:  virtualenv 虛擬環境名

安裝3.7版本python解釋器:  virtualenv -p F:\Python3.7\python37\python.exe 虛擬環境名

使用虛擬環境:在建立虛擬環境目錄下執行目錄文件  ./虛擬環境/Scripts/activate.bat

退出虛擬環境:在建立虛擬環境目錄下執行目錄文件  ./虛擬環境/Scripts/deactivate.bat

 2.項目中常用的模塊

http://www.javashuo.com/article/p-eiauibub-k.html

 3.日誌文件的配置

在項目中,因爲須要人不能24小時去監控項目是否發生異常,全部能夠經過配置文件添加日誌文件配置來保存日誌信息,

能夠在配置文件中添加一下配置

# 日誌配置
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': { 'level': 'DEBUG', 'filters': ['require_debug_true'], 'class': 'logging.StreamHandler', 'formatter': 'simple' }, 'file': { 'level': 'INFO', 'class': 'logging.handlers.RotatingFileHandler', # 日誌位置,日誌文件名,日誌保存目錄必須手動建立
            'filename': os.path.join(os.path.dirname(BASE_DIR), "logs/luffy.log"), # 日誌文件的最大值,這裏咱們設置300M
            'maxBytes': 300 * 1024 * 1024, # 日誌文件的數量,設置最大日誌數量爲10
            'backupCount': 10, # 日誌格式:詳細格式
            'formatter': 'verbose' }, }, # 日誌對象
    'loggers': { 'django': { 'handlers': ['console', 'file'], 'propagate': True, # 是否讓日誌信息繼續冒泡給其餘的日誌處理系統
 }, } }

 

此外,因爲django框架不能識別一些數據庫的錯誤,能夠自定義一個異常處理方法,而後能夠經過配置讓系統認識異常從而記錄下來

新建一個exceptions.py文件

from rest_framework.views import exception_handler from django.db import DatabaseError from rest_framework.response import Response from rest_framework import status import logging logger = logging.getLogger('django') def custom_exception_handler(exc, context): """ 自定義異常處理 :param exc: 異常類 :param context: 拋出異常的上下文 :return: Response響應對象 """
    # 調用drf框架原生的異常處理方法
    response = exception_handler(exc, context) if response is None: view = context['view'] if isinstance(exc, DatabaseError): # 數據庫異常
            logger.error('[%s] %s' % (view, exc)) response = Response({'message': '服務器內部錯誤'}, status=status.HTTP_507_INSUFFICIENT_STORAGE) return response

 

 在配置文件中添加設置

REST_FRAMEWORK = { # 異常處理
    'EXCEPTION_HANDLER': 'luffyapi.utils.exceptions.custom_exception_handler',#字典後面是自定義異常的路徑 }

 

 4.用戶登錄表

雖然django內部已經有用戶登錄的表,可是該表格不知足項目需求,須要自定義一些字段來知足不一樣的登錄方式,如微信登錄,手機登陸等

咱們能夠自定義一個類,該類繼承系統提供的登錄模型類AbstractUser

class User(AbstractUser): """用戶模型類""" mobile = models.CharField(max_length=11, unique=True, verbose_name='手機號') class Meta: db_table = 'ly_users' verbose_name = '用戶' verbose_name_plural = verbose_name

 

寫好類後須要在配置文件

AUTH_USER_MODEL = 'users.User' #app名+模型類名,不用寫models.py這個文件名,系統自動識別,全部模型類必須寫在models.py文件中

 

中告訴系統登錄時使用自定義模型類而不是使用系統提供的

用戶登錄時,默認是經過用戶名和密碼的匹配來認證登錄成功與否,但用手機號登錄時就會失敗全部能夠經過自定義類來寫登錄邏輯

def get_user_by_account(account): """ 根據賬號獲取user對象 :param account: 帳號,能夠是用戶名,也能夠是手機號 :return: User對象 或者 None """
    try: if re.match('^1[3-9]\d{9}$', account): # 賬號爲手機號
            user = User.objects.get(mobile=account) else: # 賬號爲用戶名
            user = User.objects.get(username=account) except User.DoesNotExist: return None else: return user import re from .models import User from django.contrib.auth.backends import ModelBackend class UsernameMobileAuthBackend(ModelBackend): """ 自定義用戶名或手機號認證 """

    def authenticate(self, request, username=None, password=None, **kwargs): user = get_user_by_account(username) if user is not None and user.check_password(password): return user

 

經過配置文件來告訴系統

AUTHENTICATION_BACKENDS = [ 'user.utils.UsernameMobileAuthBackend', ]

 

5.外部接口的使用

極驗驗證:   https://www.geetest.com/first_page/

雲通信發送短信: https://www.yuntongxun.com/

支付寶付款: https://open.alipay.com/platform/home.htm

保利威視頻加密:http://www.polyv.net/vod/

 

6.媒體文件的上傳

後端須要給前端發生圖片,視頻等媒體文件,須要建立一個目錄來存在這些文件,而且把該文件的目錄告訴django框架

在配置文件中添加

# 訪問靜態文件的url地址前綴
STATIC_URL = '/static/'
# 設置django的靜態文件目錄
STATICFILES_DIRS = [ os.path.join(BASE_DIR,"static") ] # 項目中存儲上傳文件的根目錄[暫時配置],注意,uploads目錄須要手動建立不然上傳文件時報錯
MEDIA_ROOT=os.path.join(BASE_DIR,"uploads") # 訪問上傳文件的url地址前綴
MEDIA_URL ="/media/"

 

 新增url

from django.urls import re_path from django.conf import settings from django.views.static import serve urlpatterns = [ ... re_path(r'media/(?P<path>.*)', serve, {"document_root": settings.MEDIA_ROOT}), ]

 7.celery

使用celery能夠異步處理一些耗時或者定時文體

安裝:pip install -U celery

使用:新建一個任務目錄

luffyapi/ ├── mycelery/ ├── config.py # 配置文件
    ├── __init__.py ├── main.py # 主程序
    └── sms/          # 一個目錄能夠放置多個任務,該目錄下存放當前任務執行時須要的模塊或依賴
        └── tasks.py  # 任務的文件,名稱必須是這個!!!

 

 在main.py中

# 主程序
from celery import Celery # 建立celery實例對象
app = Celery("luffy") # 經過app對象加載配置
app.config_from_object("mycelery.config") # 自動搜索並加載任務 # 參數必須必須是一個列表,裏面的每個任務都是任務的路徑名稱 # app.autodiscover_tasks(["任務1","任務2"])
app.autodiscover_tasks(["mycelery.sms","mycelery.cache"]) # 啓動Celery的命令 # 強烈建議切換目錄到項目的根目錄下啓動celery!! # celery -A mycelerymain worker --loglevel=info

 

 在config.py中

# 任務隊列的連接地址
broker_url = 'redis://127.0.0.1:6379/15'
# 結果隊列的連接地址
result_backend = 'redis://127.0.0.1:6379/14'

 

 在tasks.py中寫邏輯

# celery的任務必須寫在tasks.py的文件中,別的文件名稱不識別!!!
from mycelery.main import app @app.task # name表示設置任務的名稱,若是不填寫,則默認使用函數名作爲任務名
def send_sms(): print("發送短信!!!") @app.task # name表示設置任務的名稱,若是不填寫,則默認使用函數名作爲任務名
def send_sms2(): print("發送短信任務2!!!")

官方文檔http://docs.jinkan.org/docs/celery/getting-started/index.html

celery定時任務文檔:http://docs.celeryproject.org/en/latest/userguide/periodic-tasks.html

8.分頁數據

在rest_framework中已經有2個分頁器的功能的類分別是PageNumberPagination和LimitOffsetPagination,能夠自定義一個類繼承模塊提供的類就能夠自定義分頁器。

PageNumberPagination:這個類展現數據是從第m條數據開始,到m+1 ..... 一致到第n條數據,共展示n-m條數據

LimitOffsetPagination:這個類展現數據是從第m條數據開始,日後偏移n條數據,共展示m+n條數據

 

兩個類區別如圖所示,一個是經過首位數據的id來展現數據,一個是首id+偏移來展現數據

以PageNumberPagination爲例:

from rest_framework.pagination import PageNumberPagination class CustomPageNumberPagination(PageNumberPagination): # page_query_param = "" # 地址上面表明頁碼的變量名,默認爲page
    page_size = 5         # 每一頁顯示的數據量,沒有設置頁碼,則不進行分頁
    # 容許客戶端經過指定的參數名來設置每一頁數據量的大小,默認是size
    page_size_query_param = "size" max_page_size = 20    # 限制每一頁最大展現的數據量


# 按條件篩選[分類]展現課程信息
from django_filters.rest_framework import DjangoFilterBackend from rest_framework.filters import OrderingFilter from .paginations import CustomPageNumberPagination class CourseListAPIView(ListAPIView): """課程列表""" queryset = Course.objects.filter(is_show=True,is_delete=False).order_by("orders") serializer_class = CourseModelSerializer filter_backends = [DjangoFilterBackend, OrderingFilter] # 設置支持設置的篩選過濾字段
    filter_fields = ('course_category', ) # 設置支持設置的排序字段
    ordering_fields = ('id', 'students', 'price') # 指定分頁器
    pagination_class = CustomPageNumberPagination

 

9.數據庫事物開啓與回滾

在某些邏輯中可能會存在同時操做多個數據表,但不能100%保證執行成功,若是聽任報錯前的數據,會致使數據表出現不少無用數據,因此須要開啓事務

開啓事務的兩種方法

添加裝飾器

from django.db import transaction from rest_framework.views import APIView class OrderAPIView(APIView): @transaction.atomic # 開啓事務,當方法執行完成之後,自動提交事務
    def post(self,request): ....

 

使用with語句:

from django.db import transaction from rest_framework.views import APIView class OrderAPIView(APIView): def post(self,request): .... with transation.atomic(): # 設置事務回滾的標記點
            sid = transation.savepoint() .... try: .... except: transation.savepoint_rallback(sid) #報錯則回滾到標記點
相關文章
相關標籤/搜索