给你一个优秀的Django工程模板
时间:2022-07-24
本文章向大家介绍给你一个优秀的Django工程模板,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
本文原创首发于今日头条:Python集结号
经常要搭建Django的后端服务器,这里将搭建步骤记录下来,需要的同学可以参考一下,仅代表自己的编程习惯。
需要安装的Python库
- django
- djanglrestframework
- django-cors-headers
- jwt
初始化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 AbstractUser
from django.db import models
from 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.py
- authentication.py文件
import time
from django.db.models import Q
from rest_framework.authentication import BaseAuthentication
from rest_framework.exceptions import AuthenticationFailed
from users.models import UserInfo
from utils.jwt_util import JwtUtil
from 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 time
from jwt import JWT, jwk_from_dict
from django.conf import settings
class 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 = (
... '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 backends
from django.db.models import Q
from users.models import UserInfo
from utils.jwt_util import JwtUtil
class 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上,以供大家参考使用
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 使用squid搭建http和https的代理服务器设置指南
- linux中gdb的入门使用教程
- Linux命令中Ctrl+z、Ctrl+c和Ctrl+d的区别和使用详解
- Linux lseek函数的使用详解
- Nginx出现500 Internal Server Error 错误的解决方案
- Linux常见基本命令与用法大全
- Navicat 环境测试 innodb 的默认行锁升级表锁
- Ubuntu18.04更换国内源的方法示例
- 详解ubuntu双系统启动时卡死解决办法
- 轻松掌握Git开发(二)本地仓库的基本操作
- 轻松掌握Git开发(三)版本的切换
- 轻松掌握Git开发(四)分支操作
- 一文搞定pandas的透视表
- Spring 日志输出错误字符 -e[0;39m e[2m[
- linux不支持所有命令的解决办法