晒晒我家小院子

0%

使用django-cors-headers扩展解决跨域访问

安装

1
pip install django-cors-headers

配置

settings.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
INSTALLED_APPS = (
...
'corsheaders',
...
)
MIDDLEWARE = [
'corsheaders.middleware.CorsMiddleware', # 放在最前面
...
]
# CORS白名单
CORS_ORIGIN_WHITELIST = (
'127.0.0.1:8080',
'localhost:8080',
)
# 或者
CORS_ALLOW_CREDENTIALS = True # 跨域访问中,允许携带cookie
# CORS_ORIGIN_ALLOW_ALL为True, 指定所有域名(ip)都可以访问后端接口, 默认为False
CORS_ORIGIN_ALLOW_ALL = True

补充

ALLOWED_HOSTS允许访问后端的域名

1
ALLOWED_HOSTS = ['127.0.0.1', 'localhost', 'api.myard.cn']
1
ALLOWED_HOSTS = ['*']  # 填写上“*”可以使所有的网址都能访问Django项目了

django认证系统

Django的认证系统提供了认证机制和权限机制

常用方法:
  • set_password(raw_password)

    设置用户的密码为给定的原始字符串,并负责密码的。 不会保存User 对象。当Noneraw_password 时,密码将设置为一个不可用的密码。

  • check_password(raw_password)

    如果给定的raw_password是用户的真实密码,则返回True,可以在校验用户密码时使用。

管理器方法:

管理器方法即可以通过User.objects. 进行调用的方法。

  • create_user(username, email=None, password=None, *\extra_fields*)

    创建、保存并返回一个User对象。

  • create_superuser(username, email, password, *\extra_fields*)

    create_user() 相同,但是设置is_staffis_superuserTrue

创建自定义的用户模型类

models.py

1
2
3
4
5
6
7
8
9
from django.contrib.auth.models import AbstractUser
class User(AbstractUser):
"""用户模型类"""
mobile = models.CharField(max_length=11, unique=True, verbose_name='手机号')

class Meta:
db_table = 'tb_users'
verbose_name = '用户'
verbose_name_plural = verbose_name

settings.py

1
AUTH_USER_MODEL = 'users.User'

数据迁移

1
2
python manage.py makemigrations
python manage.py migrate

补充

Django中的用户认证-官方文档

异常处理

  • 修改Django REST framework的默认异常处理方法,补充处理数据库异常和Redis异常

utils/exceptions.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
from rest_framework.views import exception_handler as drf_exception_handler
import logging
from django.db import DatabaseError
from redis.exceptions import RedisError
from rest_framework.response import Response
from rest_framework import status

# 获取在配置文件中定义的logger,用来记录日志
logger = logging.getLogger('django')

def exception_handler(exc, context):
"""
自定义异常处理
:param exc: 异常
:param context: 抛出异常的上下文
:return: Response响应对象
"""
# 调用drf框架原生的异常处理方法
response = drf_exception_handler(exc, context)

if response is None:
view = context['view']
if isinstance(exc, DatabaseError) or isinstance(exc, RedisError):
# 数据库异常
logger.error('[%s] %s' % (view, exc))
response = Response({'message': '服务器内部错误'}, status=status.HTTP_507_INSUFFICIENT_STORAGE)

return response

settings.py

1
2
3
4
REST_FRAMEWORK = {
# 异常处理
'EXCEPTION_HANDLER': 'project.utils.exceptions.exception_handler',
}

本地化语言与时区

settings.py

1
2
LANGUAGE_CODE = 'zh-hans'
TIME_ZONE = 'Asia/Shanghai'

配置日志

settings.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
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在debug模式下才输出日志
'()': 'django.utils.log.RequireDebugTrue',
},
},
'handlers': { # 日志处理方法
'console': { # 向终端中输出日志
'level': 'INFO',
'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/demo.log"),
'maxBytes': 300 * 1024 * 1024,
'backupCount': 10,
'formatter': 'verbose'
},
},
'loggers': { # 日志器
'django': { # 定义了一个名为django的日志器
'handlers': ['console', 'file'], # 可以同时向终端与文件中输出日志
'propagate': True, # 是否继续传递日志信息
'level': 'INFO', # 日志器接收的最低日志级别
},
}
}