文章目录
1. settings 文件简介
Django settings文件中提供了很多配置使用,具体位置如下所示,在项目同名文件夹下。在其中添加想要的配置即可
--BBS项目文件夹 创建的项目,名称自定义
--BBS文件夹 和项目同名的文件夹
---settings.py 配置文件
---urls.py 路由与视图函数对应关系(路由层)
---wsgi.py wsgiref模块(不考虑)
--manage.py django的入口文件
--db.sqlite3 django自带的sqlite3数据库(小型数据库功能不是很多还有bug)
--myBBS文件夹 自定义的app
---admin.py django后台管理
---apps.py 注册使用
---migrations文件夹 数据库迁移记录
2. settings 文件常见配置
(2.1) app路径
该配置可以对项目中的app进行注册,使用pycharm创建Django项目额外创建的app自动注册,如上图所示。其余需要手动注册,如下示例
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
# app注册全写
'myBBS.apps.MybbsConfig',
# app注册简写方式
'myBBS'
]
(2.2) 数据库配置
数据库默认使用的是自带的sqlite3,其配置如下,我们可以指定数据库,这里以MySQL为例
# 默认配置
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
# 指定MySQL
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'mybbs', # 库名
'HOST': '127.0.0.1', # 数据库IP地址
'PORT': 3306, # 端口
'USER': 'root', # 用户名
'PASSWORD': '123', # 密码
}
}
除了在settings文件中配置外,还需要在项目同名的文件夹下的__init__.py
文件中配置一下内容
import pymysql
pymysql.install_as_MySQLdb()
'''
修改的具体内容可以参照以下网址
https://docs.djangoproject.com/en/1.11/ref/settings/#databases
'''
(2.3) 静态文件目录
开设静态文件访问接口。
项⽬中的css、image、js都是静态⽂件。⼀般会将静态⽂件放到⼀个单独的⽬录中,以⽅便管理。
在html⻚⾯中调⽤时,也需要指定静态⽂件的路径,Django中提供了⼀种解析的⽅式配置静态⽂件路径。
静态⽂件可以放在项⽬根⽬录下,也可以放在应⽤下,由于有些静态⽂件在项⽬中是通⽤的,所以推荐放在项⽬的根⽬录下
# 访问静态⽂件的URL前缀
STATIC_URL = '/static/'
# 存放查找静态⽂件的⽬录
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'static')
]
(2.4) 声明拓展表
from django.contrib.auth.models import AbstractUser
class UsersInfo(AbstractUser):
pass
指定继承了AbstractUser的自定义表UsersInfo作为后台管理系统认证表。默认使用的认证表是auth_user,如下声明了自定义表后才能生效
# 格式为 应用名.表名
AUTH_USER_MODEL = 'myBBS.UsersInfo'
(2.5) 注册自定义中间件
可以自定义中间件如下图示例,但是需要在settings中进行注册
创建自定义中间件的流程
1.创建一个任意名称的文件夹例如 middleware
2.在该文件夹内创建一个任意名称的py文件例如mymdd
3.在该py文件内编写中间件类
4.在settings配置文件中注册
注册中间件
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
# 注册自定义中间件
' middleware.mymdd. MyMdd1',
' middleware.mymdd. MyMdd2 ',
]
(2.6) 模板路径
templates 文件夹有些情况没有配置路径可以自己指定
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',
],
},
},
]
(2.7) 本地语言与时区
Django⽀持许多国家的语言,只需要修改其配置即可。能比较明显看出来的是admin后台管理系统。
# 默认配置
LANGUAGE_CODE = 'en-us' # 语⾔
TIME_ZONE = 'UTC' # 时区# 时区
# 修改为中文
LANGUAGE_CODE = 'zh-Hans'
TIME_ZONE = 'Asia/Shanghai'
(2.8) 登录装饰器跳转路由
在验证用户是否登录的时候可以使用Django自带的登录装饰器,其有一个参数login_url
用于未登录时自动跳转的页面,一般设置为登录界面
# 首先要导入模块,导入语句:
from django.contrib.auth.decorators import login_required
局部配置
使用示例
from django.contrib.auth.decorators import login_required
from django.utils.decorators import method_decorator
@method_decorator(login_required(login_url='/login/'), name='get')
class Index(View):
def get(self, request):
return HttpResponse('这是Index')
'''由于我这里使用的是类的形式,所以导入了模块 method_decorator '''
1. @login_required()
不加login_url参数路由结果 http://127.0.0.1:8000/accounts/login/?next=/index/
2. @login_required(login_url='/login/')
不加login_url参数路由结果 http://127.0.0.1:8000/login/?next=/index/
全局配置
除了在装饰器中使用 login_url 参数来指定路由外,还可以在全局中指定,在settings配置文件中指定后,所有的装饰器
都不需要添加login_url参数了,设置方式如下所示
# 配置未登录时重定向的路由
LOGIN_URL = '/login/'
(2.9) 接收用户存储的文件
开设接口让指定文件可以被外界所访问,不能轻易暴露,可以将用户上传的头像等文件暴露出去。
# 自动创建media文件夹,用于存放用户上传的内容,可以被外界访问
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
(2.10) DEBUG 配置
DEBUG = True 时 :
- 修改了Django项目的代码,然后按下 ctrl+s,那么Django就会自动的给我们重启项目,不需要手动重启。
- Django项目中的代码出现bug了,那么在浏览器中和控制台会打印出错信息。
- 在生产环境中,禁止开启 DEBUG = True,因为当你的网站出错误时,别人能看到你的源代码,而我们也不需要给用户看到这些错误信息。所以需要设置 DEBUG = False
DEBUG = False 时:
- 如果设置了 DEBUG = False,那么就必须设置 settings.py 中的 ALLOWED_HOSTS
- ALLOWED_HOSTS 是用来设置指定的 IP 地址或者域名来进行访问
(2.11) 配置JWT 过期时间
import datetime
JWT_AUTH = {
# 过期时间1天
'JWT_EXPIRATION_DELTA': datetime.timedelta(days=1),
}
3. 系统配置文件
Django有俩配置文件,一个是暴露给用户可以自定义的基本配置。也就是项目同名文件夹下的settings.py文件。还有一个配置文件是全局的系统默认的配置,当用户不修改时使用默认配置。global_settings全局配置文件中有所有的配置,例如前面写的本地语言,在里面有着完全的列举。
# 全局的系统默认的配置 global_settings,需要导入
from django.conf import global_settings
俩个配置文件之间的关系
如果在settings配置文件中指定了配置,那么会使用settings中的配置而不会使用全局配置global_settings中的配置
使用全局配置
使用全局配置的话需要使用以下导入 django.conf 下的settings文件,其可以使用global_settings中的全局配置。并且django.conf 下的settings文件还可以导用户自定义的配置,功能更加强大
# 导入语句
from django.conf import settings
# 上述的settings既可以导入暴露给用户配置文件中的所有配置也可以导入系统默认的配置
(3.1) django 配置文件源码
我们可以查看django.conf 下的settings文件源码了解大致核心内容
1. 查看其源码发现其实settings是一个类实例对象
settings = LazySettings()
2. 查看 LazySettings类
class LazySettings(LazyObject):
def _setup(self, name=None):
# 获取暴露给用户的settings文件路径,例如BBS.settings
settings_module = os.environ.get(ENVIRONMENT_VARIABLE)
if not settings_module:
desc = ("setting %s" % name) if name else "settings"
raise ImproperlyConfigured(
% (desc, ENVIRONMENT_VARIABLE))
# 将暴露给用户的settings文件路径传入Settings类中
self._wrapped = Settings(settings_module)
.........
3. 了解 os.environ
(1)LazySettings 类中的 settings_module是从 os.environ中获得的
(2)os.environ 可以获取环境变量,其可以看成是一个字典,环境变量的字典。
(3)而 settings_module获取的是 ENVIRONMENT_VARIABLE对应的字符串键名
(4)查看 ENVIRONMENT_VARIABLE的源码发现其对应的是 "DJANGO_SETTINGS_MODULE"
(5)这个键值对是在 manage.py 中设置的,如下示例
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "BBS.settings")
(6)该语法为 os.environ.setdefault('环境变量名称', '环境变量值'),可以添加键值对
(7)也就是说 settings_module使用了get方法获取键名为 DJANGO_SETTINGS_MODULE,得到的
键值为暴露给用户的settings文件路径
4. 在LazySettings类源代码中可以看到其将暴露给用户的settings文件路径传入Settings类中,查看Settings类源码
class Settings(object):
# settings_module 为暴露给用户的settings文件路径,例如 BBS.settings
def __init__(self, settings_module):
# 获取global_settings系统配置文件中所有变量名
for setting in dir(global_settings):
# 校验变量名是否为大写,因此我们自定义配置时候需要大写才能生效
if setting.isupper():
# 查看第5步解释
setattr(self, setting, getattr(global_settings, setting))
# 将 BBS.settings 赋值给 SETTINGS_MODULE
self.SETTINGS_MODULE = settings_module
# 通过字符串类导入模块,相当于 from BBS import settings
mod = importlib.import_module(self.SETTINGS_MODULE)
tuple_settings = (
"INSTALLED_APPS",
"TEMPLATE_DIRS",
"LOCALE_PATHS",
)
self._explicit_settings = set()
# 循环获取暴露给用户的settings文件中的变量名
for setting in dir(mod):
if setting.isupper():
# 利用反射获取对应的值
setting_value = getattr(mod, setting)
if (setting in tuple_settings and
not isinstance(setting_value, (list, tuple))):
raise ImproperlyConfigured("The %s setting must be a list or a tuple. " % setting)
# 给对象设置属性
setattr(self, setting, setting_value)
self._explicit_settings.add(setting)
.......................
5. 在Settings类源码有一句 setattr(self, setting, getattr(global_settings, setting))
首先看 getattr(global_settings, setting),它通过反射获取global_settings中的所有变量
在看 setattr(self, setting, getattr(global_settings, setting)),其中setting是字符串变量名,
也就是将系统配置文件中的所有大写变量名和变量值都赋值给Settings对象
6. 简单来说就是先去循环加载系统配置文件中的属性,然后在循环加载用户自定义的属性进行替换
(3.2) 模拟settings设计
我们可以依照上述设计创建settings文件,如下所示
文件结构
我的文件结构如下所示
settings.py 代码
NAME = '我是暴露给用户的配置文件变量'
global_settings.py 代码
NAME = '我是系统配置文件中的变量'
双下 init 代码
import importlib
import os
from lib.conf import global_settings
class Settings(object):
def __init__(self):
# 循环获取全局配置文件中的所有变量
for name in dir(global_settings):
if name.isupper():
# 获取对应的值
value = getattr(global_settings, name)
# 给对象设置键值对
setattr(self, name, value)
# 获得用户自定义配置文件的字符串路径
module_path_str = os.environ.get('xxx')
# 使用字符串导入模块
module_name = importlib.import_module(module_path_str)
# 循环获取用户配置文件中的所有变量
for name in dir(module_name):
if name.isupper():
value = getattr(module_name, name)
# 设置变量
setattr(self, name, value)
# 实例化
settings = Settings()
start.py 代码
import os
import sys
sys.path.append(os.path.dirname(__file__))
if __name__ == '__main__':
# 将暴露给用户的配置文件字符串路径添加到环境变量字典中
os.environ['xxx'] = 'app.settings'
# 导入系统配置文件,其实导入的是 __init__文件中的settings
from lib.conf import settings
print(settings.NAME)