經常要搭建Django的後端伺服器,這裡將搭建步驟記錄下來,需要的同學可以參考一下,僅代表自己的程式設計習慣。
需要安裝的Python庫
djangodjanglrestframeworkdjango-cors-headersjwt初始化Django工程django-admin startproject xingxing
建立好工程後,我們要對目錄和配置進行一些調整,首先在根目錄下建立兩個目錄:apps和settings,將所有的app都存放到apps目錄裡面,把settings配置存放在settings目錄下,這樣我們的根目錄就更加清晰了.
調整settings配置首先將xingxing目錄下的settings.py檔案拷貝到settings目錄下,建立dev.py和pro.py兩個檔案,主要用於開發配置和部署配置,將settings.py檔案中的資料庫配置和DEBUG移到這兩個檔案中,內容如下:
在settings.py檔案中把apps新增到環境變數中
修改語言和時區
修改manage.py檔案將Django環境變數設定為開發環境
修改wsgi.py檔案將Django環境變數設定為釋出環境
增加多資料庫配置在xingxing目錄下增加router.py檔案路由配置檔案當中的返回值是我們在DATABASES中配置的鍵,預設是default,按照一定的條件返回不同的鍵,每個鍵內配置不同的資料庫連線,就可以實現Django專案連線多個數據庫
class CustomRouter: def db_for_read(self, model, **hints): return 'default' def db_for_write(self, model, **hints): return 'default' def allow_relation(self, obj1, obj2, **hints): return 'default' def allow_migrate(self, db, app_label, model_name=None, **hints): return 'default'
在settings.py檔案中增加路由配置
DATABASE_ROUTERS = ['xingxing.router.CustomRouter']
設定自定義使用者模型在apps下增加users應用在models.py下增加如下內容
from django.contrib.auth.models import AbstractUserfrom django.db import modelsfrom uuid import uuid4# Create your models here.class UserInfo(AbstractUser): uid = models.CharField(max_length=36, default=uuid4, primary_key=True) nickname = models.CharField(max_length=32, verbose_name='暱稱') telephone = models.CharField(max_length=11, blank=True, null=True, unique=True, verbose_name='手機號碼') create_time = models.DateTimeField(auto_now_add=True, verbose_name='建立時間') class Meta: db_table = 'tbl_user'
在settings.py中增加如下內容
INSTALLED_APPS = [ ... 'users']AUTH_USER_MODEL = 'users.UserInfo'
解決跨域問題為什麼會有跨域問題,這裡就不做詳細解釋了,可以看一下兩篇文章
前後端分離djangorestframework——解決跨域請求Django跨域驗證及OPTIONS請求在settings.py檔案中做如下配置
INSTALLED_APPS = [ ... 'corsheaders' ...]MIDDLEWARE = [ ... 'corsheaders.middleware.CorsMiddleware', # 注意必須放在CommonMiddleware前面 ...]CORS_ALLOW_CREDENTIALS = TrueCORS_ORIGIN_ALLOW_ALL = TrueCORS_ALLOW_METHODS = ( 'DELETE', 'GET', 'OPTIONS', 'PATCH', 'POST', 'PUT', 'VIEW',)CORS_ALLOW_HEADERS = ( 'XMLHttpRequest', 'X_FILENAME', 'accept-encoding', 'authorization', 'content-type', 'dnt', 'origin', 'user-agent', 'x-csrftoken', 'x-requested-with', 'Pragma', 'access-token')
jwt登入認證我們使用rest api介面,一般就很少使用使用者名稱和密碼認真,jwt認證是比較常用的,因此這也是專案初始化必須做的。
在根目錄下增加utils目錄,增加兩個檔案authentication.py和jwt_util.pyauthentication.py檔案import timefrom django.db.models import Qfrom rest_framework.authentication import BaseAuthenticationfrom rest_framework.exceptions import AuthenticationFailedfrom users.models import UserInfofrom utils.jwt_util import JwtUtilfrom threading import local_thread_local = local()class JwtAuthentication(BaseAuthentication): def authenticate(self, request): access_token = request.META.get('HTTP_ACCESS_TOKEN', None) if access_token: jwt = JwtUtil() data = jwt.check_jwt_token(access_token) if data: username = data.get('username') telephone = data.get('telephone') exp = data.get('exp') if time.time() > exp: raise AuthenticationFailed('authentication time out') try: user = UserInfo.objects.get(Q(username=username) | Q(telephone=telephone)) _thread_local.user = user except (UserInfo.DoesNotExist, UserInfo.MultipleObjectsReturned) as e: return (None, None) else: return (user, None) raise AuthenticationFailed('authentication failed')def get_current_user(): return getattr(_thread_local, 'user', None)
jwt_util.py檔案import timefrom jwt import JWT, jwk_from_dictfrom django.conf import settingsclass JwtUtil: def __init__(self): self.verifying_key = jwk_from_dict({ 'kty': 'oct', 'kid': 'HMAC key used in JWS A.1 example', 'k': settings.SECRET_KEY }) def gen_jwt_token(self, user): token_dict = { 'username': user.username, 'phone': user.telephone, 'exp': time.time() + 24 * 3600, 'iat': time.time() } obj = JWT() token = obj.encode(token_dict, key=self.verifying_key) return token def check_jwt_token(self, value): obj = JWT() data = None try: data = obj.decode(value, key=self.verifying_key) except Exception as e: print(e) return data
在settings.py中增加跨域認證的欄位CORS_ALLOW_HEADERS = (\t... 'access-token')REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': [ 'utils.authentications.JwtAuthentication' ], 'DATETIME_FORMAT': '%Y-%m-%d %H:%M:%S', 'DATETIME_INPUT_FORMATS': '%Y-%m-%d %H:%M:%S'}
修改登入認證為JWT方式在utils目錄建立user_backend.py檔案
from django.contrib.auth import backendsfrom django.db.models import Qfrom users.models import UserInfofrom utils.jwt_util import JwtUtilclass UserBackend(backends.ModelBackend): def authenticate(self, request, username=None, password=None, **kwargs): user = UserInfo.objects.get(Q(username=username) | Q(telephone=username)) if user.check_password(password): jwt = JwtUtil() token = jwt.gen_jwt_token(user) user.token = token return user raise UserInfo.DoesNotExist( "UserInfo matching query does not exist." )
在settings中設定自定義認證方式AUTHENTICATION_BACKENDS = ['utils.user_backend.UserBackend']
Django日誌記錄
在settings.py中增加如下配置:
# 日誌配置LOGGING = { "version": 1, # True表示禁用logger "disable_existing_loggers": False, 'formatters': { 'default': { 'format': '%(levelno)s %(module)s %(asctime)s %(message)s ', 'datefmt': '%Y-%m-%d %A %H:%M:%S', }, }, 'handlers': { 'request_handlers': { 'level': 'DEBUG', # 日誌檔案指定為5M, 超過5m重新命名,然後寫入新的日誌檔案 'class': 'logging.handlers.RotatingFileHandler', # 指定檔案大小 'maxBytes': 5 * 1024, # 指定檔案地址 'filename': '%s/request.log' % LOG_PATH, 'formatter': 'default' } }, 'loggers': { 'request': { 'handlers': ['request_handlers'], 'level': 'INFO' } }, 'filters': { # 過濾器 }}
在所有需要記錄日誌的檔案中採用如下方式使用
import logging...LOG = logging.getLogger('request')class RegisterView(APIView): authentication_classes = [] def post(self, request): ... LOG.info('使用者: %s 註冊成功', username) ...
其他
還有一些其他的模組,例如serializers等,整個模板工程我會上傳到GitHub上,以供大家參考使用
最新評論