dev.py
1 """ 2 Django settings for luffy project. 3 4 Generated by \'django-admin startproject\' using Django 2.2.1. 5 6 For more information on this file, see 7 https://docs.djangoproject.com/en/2.2/topics/settings/ 8 9 For the full list of settings and their values, see 10 https://docs.djangoproject.com/en/2.2/ref/settings/ 11 """ 12 13 import os 14 15 # Build paths inside the project like this: os.path.join(BASE_DIR, ...) 16 BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 17 18 19 # 新增一个系统导包路径 20 import sys 21 sys.path.insert(0, os.path.join(BASE_DIR, "apps")) 22 23 24 # Quick-start development settings - unsuitable for production 25 # See https://docs.djangoproject.com/en/2.2/howto/deployment/checklist/ 26 27 # SECURITY WARNING: keep the secret key used in production secret! 28 SECRET_KEY = \'i3bobljnf8_l&80^vxzdn^sp)tj9c4zdw3v7s^_w!365(lw_bv\' 29 30 # SECURITY WARNING: don\'t run with debug turned on in production! 31 DEBUG = True 32 33 34 # 设置哪些客户端可以通过地址访问到后端 35 ALLOWED_HOSTS = [ 36 \'api.luffycity.cn\', 37 ] 38 39 # CORS组的配置信息---添加白名单 40 CORS_ORIGIN_WHITELIST = ( 41 \'http://www.luffycity.cn:8080\', 42 ) 43 CORS_ALLOW_CREDENTIALS = True # 允许ajax跨域请求时携带cookie 44 45 46 # Application definition 47 48 INSTALLED_APPS = [ 49 \'django.contrib.admin\', 50 \'django.contrib.auth\', 51 \'django.contrib.contenttypes\', 52 \'django.contrib.sessions\', 53 \'django.contrib.messages\', 54 \'django.contrib.staticfiles\', 55 56 # 添加cors跨域组件---添加应用 57 \'corsheaders\', 58 \'rest_framework\', 59 60 \'xadmin\', 61 \'crispy_forms\', 62 \'reversion\', 63 \'django_filters\', 64 \'ckeditor\', # 富文本编辑器 65 \'ckeditor_uploader\', # 富文本编辑器上传图片模块 66 67 # 子应用 68 \'home\', 69 \'users\', 70 \'courses\', 71 \'cart\', 72 \'orders\', 73 \'coupon\', 74 \'payments\', 75 76 ] 77 78 MIDDLEWARE = [ 79 \'corsheaders.middleware.CorsMiddleware\', # 添加cors中间件(跨域相关)---中间层设置【必须写在第一个位置】 80 \'django.middleware.security.SecurityMiddleware\', 81 \'django.contrib.sessions.middleware.SessionMiddleware\', 82 \'django.middleware.common.CommonMiddleware\', 83 \'django.middleware.csrf.CsrfViewMiddleware\', 84 \'django.contrib.auth.middleware.AuthenticationMiddleware\', 85 \'django.contrib.messages.middleware.MessageMiddleware\', 86 \'django.middleware.clickjacking.XFrameOptionsMiddleware\', 87 ] 88 89 ROOT_URLCONF = \'luffy.urls\' 90 91 TEMPLATES = [ 92 { 93 \'BACKEND\': \'django.template.backends.django.DjangoTemplates\', 94 \'DIRS\': [], 95 \'APP_DIRS\': True, 96 \'OPTIONS\': { 97 \'context_processors\': [ 98 \'django.template.context_processors.debug\', 99 \'django.template.context_processors.request\', 100 \'django.contrib.auth.context_processors.auth\', 101 \'django.contrib.messages.context_processors.messages\', 102 ], 103 }, 104 }, 105 ] 106 107 WSGI_APPLICATION = \'luffy.wsgi.application\' 108 109 """ 110 自定义用户模型类 111 配置有两项注意的地方: 112 1. 值的格式只能接收两段写法, 必须是 \'子应用目录名.模型类名\' 113 2. AUTH_USER_MODEL参数的设置一定要在第一次数据库迁移之前就设置好, 114 否则后续使用可能出现未知错误。 115 """ 116 117 AUTH_USER_MODEL = \'users.User\' 118 119 # Database 120 # https://docs.djangoproject.com/en/2.2/ref/settings/#databases 121 122 DATABASES = { 123 # 默认数据库 124 \'default\': { 125 \'ENGINE\': \'django.db.backends.mysql\', 126 \'HOST\': \'127.0.0.1\', 127 \'PORT\': 3306, 128 \'USER\': \'luffy_user\', 129 \'PASSWORD\': \'luffy\', 130 \'NAME\': \'luffycity\', 131 } 132 } 133 134 135 # redis缓存配置 136 CACHES = { 137 # 默认缓存 138 "default": { 139 "BACKEND": "django_redis.cache.RedisCache", 140 # 项目上线时,需要调整这里的路径 141 "LOCATION": "redis://127.0.0.1:6379/0", 142 143 "OPTION": { 144 "CLIENT_CLASS": "django_redis.client.DefaultClient", 145 } 146 }, 147 148 "session": { 149 "BACKEND": "django_redis.cache.RedisCache", 150 # 项目上线时,需要调整这里的路径 151 "LOCATION": "redis://127.0.0.1:6379/1", 152 153 "OPTIONS": { 154 "CLIENT_CLASS": "django_redis.client.DefaultClient", 155 } 156 }, 157 158 # 提供存储短信验证码 159 "sms_code": { 160 "BACKEND": "django_redis.cache.RedisCache", 161 "LOCATION": "redis://127.0.0.1:6379/2", 162 "OPTIONS": { 163 "CLIENT_CLASS": "django_redis.client.DefaultClient", 164 } 165 }, 166 167 # 因为购物车中的商品(课程)信息会经常被用户操作,所以为了减轻服务器的压力,可以选择把购物车信息通过redis来存储. 168 "cart": { 169 "BACKEND": "django_redis.cache.RedisCache", 170 "LOCATION": "redis://127.0.0.1:6379/3", 171 "OPTIONS": { 172 "CLIENT_CLASS": "django_redis.client.DefaultClient", 173 } 174 }, 175 176 } 177 178 # 设置xadmin用户登录时,登录信息session保存到redis 179 SESSION_ENGINE = "django.contrib.sessions.backends.cache" 180 SESSION_CACHE_ALIAS = "session" 181 182 183 # Password validation 184 # https://docs.djangoproject.com/en/2.2/ref/settings/#auth-password-validators 185 186 AUTH_PASSWORD_VALIDATORS = [ 187 { 188 \'NAME\': \'django.contrib.auth.password_validation.UserAttributeSimilarityValidator\', 189 }, 190 { 191 \'NAME\': \'django.contrib.auth.password_validation.MinimumLengthValidator\', 192 }, 193 { 194 \'NAME\': \'django.contrib.auth.password_validation.CommonPasswordValidator\', 195 }, 196 { 197 \'NAME\': \'django.contrib.auth.password_validation.NumericPasswordValidator\', 198 }, 199 ] 200 201 202 # Internationalization 203 # https://docs.djangoproject.com/en/2.2/topics/i18n/ 204 205 # 修改使用中文界面 206 LANGUAGE_CODE = \'zh-Hans\' 207 208 # 修改时区 209 TIME_ZONE = \'Asia/Shanghai\' 210 211 USE_I18N = True 212 213 USE_L10N = True 214 215 USE_TZ = False 216 217 218 # Static files (CSS, JavaScript, Images) 219 # https://docs.djangoproject.com/en/2.2/howto/static-files/ 220 221 # 访问静态文件的url地址前缀 222 STATIC_URL = \'/static/\' 223 224 # 设置django的静态文件目录 225 STATICFILES_DIRS = [ 226 os.path.join(BASE_DIR, "/statics") 227 ] 228 229 # 项目中存储上传文件的根目录[暂时配置],注意,static目录需要手动创建否则上传文件时报错 230 MEDIA_ROOT = os.path.join(BASE_DIR, "statics") 231 # print("============", BASE_DIR) 232 # print(MEDIA_ROOT) 233 # 访问上传文件的url地址前缀 234 MEDIA_URL = "/media/" 235 236 237 # 日志配置 238 LOGGING = { 239 \'version\': 1, 240 \'disable_existing_loggers\': False, 241 \'formatters\': { 242 \'verbose\': { 243 \'format\': \'%(levelname)s %(asctime)s %(module)s %(lineno)d %(message)s\' 244 }, 245 \'simple\': { 246 \'format\': \'%(levelname)s %(module)s %(lineno)d %(message)s\' 247 }, 248 }, 249 \'filters\': { 250 \'require_debug_true\': { 251 \'()\': \'django.utils.log.RequireDebugTrue\', 252 }, 253 }, 254 \'handlers\': { 255 \'console\': { 256 \'level\': \'DEBUG\', 257 \'filters\': [\'require_debug_true\'], 258 \'class\': \'logging.StreamHandler\', 259 \'formatter\': \'simple\' 260 }, 261 \'file\': { 262 \'level\': \'INFO\', 263 \'class\': \'logging.handlers.RotatingFileHandler\', 264 # 日志位置,日志文件名,日志保存目录必须手动创建 265 \'filename\': os.path.join(os.path.dirname(BASE_DIR), "logs/luffy.log"), 266 # 日志文件的最大值,这里我们设置300M 267 \'maxBytes\': 300 * 1024 * 1024, 268 # 日志文件的数量,设置最大日志数量为10 269 \'backupCount\': 10, 270 # 日志格式:详细格式 271 \'formatter\': \'verbose\' 272 }, 273 }, 274 # 日志对象 275 \'loggers\': { 276 \'luffy\': { 277 \'handlers\': [\'console\', \'file\'], 278 \'propagate\': True, # 是否让日志信息继续冒泡给其他的日志处理系统 279 }, 280 } 281 } 282 283 284 REST_FRAMEWORK = { 285 # 异常处理 286 \'EXCEPTION_HANDLER\': \'luffy.utils.exceptions.custom_exception_handler\', 287 288 # 配置JWT 289 \'DEFAULT_AUTHENTICATION_CLASSES\': ( 290 \'rest_framework_jwt.authentication.JSONWebTokenAuthentication\', 291 \'rest_framework.authentication.SessionAuthentication\', 292 \'rest_framework.authentication.BasicAuthentication\', 293 ), 294 } 295 296 297 import datetime 298 JWT_AUTH = { 299 # 配置jwt的有效期为 1天 300 \'JWT_EXPIRATION_DELTA\': datetime.timedelta(days=1), 301 # 设置jwt登录视图的返回值 302 \'JWT_RESPONSE_PAYLOAD_HANDLER\': \'users.utils.jwt_response_payload_handler\', 303 304 } 305 306 307 308 # 配置django的认证类功能,增加手机号码登录 309 AUTHENTICATION_BACKENDS = [ 310 \'users.utils.UsernameMobileAuthBackend\', 311 ] 312 313 # 极验验证码配置 314 PC_GEETEST_ID = \'5f4ab1914455506edffaffd4da37fea5\' 315 PC_GEETEST_KEY =\'460e13a49d687e5e44e25c383f0473a6\' 316 317 318 # 短信配置(注册时的短信验证码) 319 # 主账号 320 SMS_ACCOUNTSID = \'8a216da86ab0b4d2016abb6209740948\' 321 322 # 主账号Token 323 SMS_ACCOUNTTOKEN = \'1fb208011c9a45babb84807fd3af13b7\' 324 325 # 创建应用的APPID 326 SMS_APPID = \'8a216da86ab0b4d2016abb6209c8094e\' 327 328 # 说明:请求地址,生产环境配置成app.cloopen.com 329 SMS_SERVERIP = \'sandboxapp.cloopen.com\' 330 331 332 # 富文本编辑器ckeditor配置 333 CKEDITOR_CONFIGS = { 334 \'default\': { 335 \'toolbar\': \'full\', # 工具条功能 336 \'height\': 300, # 编辑器高度 337 # \'width\': 300, # 编辑器宽 338 }, 339 } 340 CKEDITOR_UPLOAD_PATH = \'\' # 上传图片保存路径,留空则调用django的文件上传功能 341 342 343 # 保利威视频加密服务 344 POLYV_CONFIG = { 345 "userId": "2ed6a0347e", 346 "secretkey": "ubWpbwKsi8", 347 "servicesUrl": "https://hls.videocc.net/service/v1/token", 348 } 349 350 351 # 支付宝电脑网站支付配置信息 352 ALIPAY_APPID = "2016093000628296" # 应用ID (APPID:2016093000628296) 353 APP_NOTIFY_URL = None # 应用回调地址[支付成功以后,支付宝返回结果到哪一个地址下面] 354 ALIPAY_DEBUG = True # APIPAY_GATEWAY="https://openapi.alipay.com/gateway.do" 355 356 APIPAY_GATEWAY="https://openapi.alipaydev.com/gateway.do" 357 ALIPAY_RETURN_URL = "http://www.luffycity.cn:8080/success" 358 ALIPAY_NOTIFY_URL = "http://api.luffycity.cn:8000/payments/success"
prop.py
1 """ 2 Django settings for luffy project. 3 4 Generated by \'django-admin startproject\' using Django 2.2.1. 5 6 For more information on this file, see 7 https://docs.djangoproject.com/en/2.2/topics/settings/ 8 9 For the full list of settings and their values, see 10 https://docs.djangoproject.com/en/2.2/ref/settings/ 11 """ 12 13 import os 14 15 # Build paths inside the project like this: os.path.join(BASE_DIR, ...) 16 BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 17 18 19 # 新增一个系统导包路径 20 import sys 21 sys.path.insert(0, os.path.join(BASE_DIR, "apps")) 22 23 24 # Quick-start development settings - unsuitable for production 25 # See https://docs.djangoproject.com/en/2.2/howto/deployment/checklist/ 26 27 # SECURITY WARNING: keep the secret key used in production secret! 28 SECRET_KEY = \'i3bobljnf8_l&80^vxzdn^sp)tj9c4zdw3v7s^_w!365(lw_bv\' 29 30 # SECURITY WARNING: don\'t run with debug turned on in production! 31 DEBUG = True 32 33 34 # 设置哪些客户端可以通过地址访问到后端 35 ALLOWED_HOSTS = [ 36 \'api.luffycity.cn\', 37 ] 38 39 # CORS组的配置信息---添加白名单 40 CORS_ORIGIN_WHITELIST = ( 41 \'http://www.luffycity.cn:8080\', 42 ) 43 CORS_ALLOW_CREDENTIALS = True # 允许ajax跨域请求时携带cookie 44 45 46 # Application definition 47 48 INSTALLED_APPS = [ 49 \'django.contrib.admin\', 50 \'django.contrib.auth\', 51 \'django.contrib.contenttypes\', 52 \'django.contrib.sessions\', 53 \'django.contrib.messages\', 54 \'django.contrib.staticfiles\', 55 56 # 添加cors跨域组件---添加应用 57 \'corsheaders\', 58 \'rest_framework\', 59 60 \'xadmin\', 61 \'crispy_forms\', 62 \'reversion\', 63 \'django_filters\', 64 \'ckeditor\', # 富文本编辑器 65 \'ckeditor_uploader\', # 富文本编辑器上传图片模块 66 67 # 子应用 68 \'home\', 69 \'users\', 70 \'courses\', 71 \'cart\', 72 \'orders\', 73 \'coupon\', 74 \'payments\', 75 76 ] 77 78 MIDDLEWARE = [ 79 \'corsheaders.middleware.CorsMiddleware\', # 添加cors中间件(跨域相关)---中间层设置【必须写在第一个位置】 80 \'django.middleware.security.SecurityMiddleware\', 81 \'django.contrib.sessions.middleware.SessionMiddleware\', 82 \'django.middleware.common.CommonMiddleware\', 83 \'django.middleware.csrf.CsrfViewMiddleware\', 84 \'django.contrib.auth.middleware.AuthenticationMiddleware\', 85 \'django.contrib.messages.middleware.MessageMiddleware\', 86 \'django.middleware.clickjacking.XFrameOptionsMiddleware\', 87 ] 88 89 ROOT_URLCONF = \'luffy.urls\' 90 91 TEMPLATES = [ 92 { 93 \'BACKEND\': \'django.template.backends.django.DjangoTemplates\', 94 \'DIRS\': [], 95 \'APP_DIRS\': True, 96 \'OPTIONS\': { 97 \'context_processors\': [ 98 \'django.template.context_processors.debug\', 99 \'django.template.context_processors.request\', 100 \'django.contrib.auth.context_processors.auth\', 101 \'django.contrib.messages.context_processors.messages\', 102 ], 103 }, 104 }, 105 ] 106 107 WSGI_APPLICATION = \'luffy.wsgi.application\' 108 109 """ 110 自定义用户模型类 111 配置有两项注意的地方: 112 1. 值的格式只能接收两段写法, 必须是 \'子应用目录名.模型类名\' 113 2. AUTH_USER_MODEL参数的设置一定要在第一次数据库迁移之前就设置好, 114 否则后续使用可能出现未知错误。 115 """ 116 117 AUTH_USER_MODEL = \'users.User\' 118 119 # Database 120 # https://docs.djangoproject.com/en/2.2/ref/settings/#databases 121 122 DATABASES = { 123 # 默认数据库 124 \'default\': { 125 \'ENGINE\': \'django.db.backends.mysql\', 126 \'HOST\': \'127.0.0.1\', 127 \'PORT\': 3306, 128 \'USER\': \'luffy_user\', 129 \'PASSWORD\': \'luffy\', 130 \'NAME\': \'luffycity\', 131 } 132 } 133 134 135 # redis缓存配置 136 CACHES = { 137 # 默认缓存 138 "default": { 139 "BACKEND": "django_redis.cache.RedisCache", 140 # 项目上线时,需要调整这里的路径 141 "LOCATION": "redis://127.0.0.1:6379/0", 142 143 "OPTION": { 144 "CLIENT_CLASS": "django_redis.client.DefaultClient", 145 } 146 }, 147 148 "session": { 149 "BACKEND": "django_redis.cache.RedisCache", 150 # 项目上线时,需要调整这里的路径 151 "LOCATION": "redis://127.0.0.1:6379/1", 152 153 "OPTIONS": { 154 "CLIENT_CLASS": "django_redis.client.DefaultClient", 155 } 156 }, 157 158 # 提供存储短信验证码 159 "sms_code": { 160 "BACKEND": "django_redis.cache.RedisCache", 161 "LOCATION": "redis://127.0.0.1:6379/2", 162 "OPTIONS": { 163 "CLIENT_CLASS": "django_redis.client.DefaultClient", 164 } 165 }, 166 167 # 因为购物车中的商品(课程)信息会经常被用户操作,所以为了减轻服务器的压力,可以选择把购物车信息通过redis来存储. 168 "cart": { 169 "BACKEND": "django_redis.cache.RedisCache", 170 "LOCATION": "redis://127.0.0.1:6379/3", 171 "OPTIONS": { 172 "CLIENT_CLASS": "django_redis.client.DefaultClient", 173 } 174 }, 175 176 } 177 178 # 设置xadmin用户登录时,登录信息session保存到redis 179 SESSION_ENGINE = "django.contrib.sessions.backends.cache" 180 SESSION_CACHE_ALIAS = "session" 181 182 183 # Password validation 184 # https://docs.djangoproject.com/en/2.2/ref/settings/#auth-password-validators 185 186 AUTH_PASSWORD_VALIDATORS = [ 187 { 188 \'NAME\': \'django.contrib.auth.password_validation.UserAttributeSimilarityValidator\', 189 }, 190 { 191 \'NAME\': \'django.contrib.auth.password_validation.MinimumLengthValidator\', 192 }, 193 { 194 \'NAME\': \'django.contrib.auth.password_validation.CommonPasswordValidator\', 195 }, 196 { 197 \'NAME\': \'django.contrib.auth.password_validation.NumericPasswordValidator\', 198 }, 199 ] 200 201 202 # Internationalization 203 # https://docs.djangoproject.com/en/2.2/topics/i18n/ 204 205 # 修改使用中文界面 206 LANGUAGE_CODE = \'zh-Hans\' 207 208 # 修改时区 209 TIME_ZONE = \'Asia/Shanghai\' 210 211 USE_I18N = True 212 213 USE_L10N = True 214 215 USE_TZ = False 216 217 218 # Static files (CSS, JavaScript, Images) 219 # https://docs.djangoproject.com/en/2.2/howto/static-files/ 220 221 # 访问静态文件的url地址前缀 222 STATIC_URL = \'/static/\' 223 224 # 设置django的静态文件目录 225 STATICFILES_DIRS = [ 226 os.path.join(BASE_DIR, "statics") 227 ] 228 229 # 收集静态文件 ----------------------------------------------------------------------------- 230 STATIC_ROOT = os.path.join(os.path.dirname(BASE_DIR), \'static\') 231 232 # 项目中存储上传文件的根目录[暂时配置],注意,static目录需要手动创建否则上传文件时报错 233 MEDIA_ROOT = os.path.join(BASE_DIR, "statics") 234 # print("============", BASE_DIR) 235 # print(MEDIA_ROOT) 236 # 访问上传文件的url地址前缀 237 MEDIA_URL = "/media/" 238 239 240 # 日志配置 241 LOGGING = { 242 \'version\': 1, 243 \'disable_existing_loggers\': False, 244 \'formatters\': { 245 \'verbose\': { 246 \'format\': \'%(levelname)s %(asctime)s %(module)s %(lineno)d %(message)s\' 247 }, 248 \'simple\': { 249 \'format\': \'%(levelname)s %(module)s %(lineno)d %(message)s\' 250 }, 251 }, 252 \'filters\': { 253 \'require_debug_true\': { 254 \'()\': \'django.utils.log.RequireDebugTrue\', 255 }, 256 }, 257 \'handlers\': { 258 \'console\': { 259 \'level\': \'DEBUG\', 260 \'filters\': [\'require_debug_true\'], 261 \'class\': \'logging.StreamHandler\', 262 \'formatter\': \'simple\' 263 }, 264 \'file\': { 265 \'level\': \'INFO\', 266 \'class\': \'logging.handlers.RotatingFileHandler\', 267 # 日志位置,日志文件名,日志保存目录必须手动创建 268 \'filename\': os.path.join(os.path.dirname(BASE_DIR), "logs/luffy.log"), 269 # 日志文件的最大值,这里我们设置300M 270 \'maxBytes\': 300 * 1024 * 1024, 271 # 日志文件的数量,设置最大日志数量为10 272 \'backupCount\': 10, 273 # 日志格式:详细格式 274 \'formatter\': \'verbose\' 275 }, 276 }, 277 # 日志对象 278 \'loggers\': { 279 \'luffy\': { 280 \'handlers\': [\'console\', \'file\'], 281 \'propagate\': True, # 是否让日志信息继续冒泡给其他的日志处理系统 282 }, 283 } 284 } 285 286 287 REST_FRAMEWORK = { 288 # 异常处理 289 \'EXCEPTION_HANDLER\': \'luffy.utils.exceptions.custom_exception_handler\', 290 291 # 配置JWT 292 \'DEFAULT_AUTHENTICATION_CLASSES\': ( 293 \'rest_framework_jwt.authentication.JSONWebTokenAuthentication\', 294 \'rest_framework.authentication.SessionAuthentication\', 295 \'rest_framework.authentication.BasicAuthentication\', 296 ), 297 } 298 299 300 import datetime 301 JWT_AUTH = { 302 # 配置jwt的有效期为 1天 303 \'JWT_EXPIRATION_DELTA\': datetime.timedelta(days=1), 304 # 设置jwt登录视图的返回值 305 \'JWT_RESPONSE_PAYLOAD_HANDLER\': \'users.utils.jwt_response_payload_handler\', 306 307 } 308 309 310 311 # 配置django的认证类功能,增加手机号码登录 312 AUTHENTICATION_BACKENDS = [ 313 \'users.utils.UsernameMobileAuthBackend\', 314 ] 315 316 # 极验验证码配置 317 PC_GEETEST_ID = \'5f4ab1914455506edffaffd4da37fea5\' 318 PC_GEETEST_KEY =\'460e13a49d687e5e44e25c383f0473a6\' 319 320 321 # 短信配置(注册时的短信验证码) 322 # 主账号 323 SMS_ACCOUNTSID = \'8a216da86ab0b4d2016abb6209740948\' 324 325 # 主账号Token 326 SMS_ACCOUNTTOKEN = \'1fb208011c9a45babb84807fd3af13b7\' 327 328 # 创建应用的APPID 329 SMS_APPID = \'8a216da86ab0b4d2016abb6209c8094e\' 330 331 # 说明:请求地址,生产环境配置成app.cloopen.com 332 SMS_SERVERIP = \'sandboxapp.cloopen.com\' 333 334 335 # 富文本编辑器ckeditor配置 336 CKEDITOR_CONFIGS = { 337 \'default\': { 338 \'toolbar\': \'full\', # 工具条功能 339 \'height\': 300, # 编辑器高度 340 # \'width\': 300, # 编辑器宽 341 }, 342 } 343 CKEDITOR_UPLOAD_PATH = \'\' # 上传图片保存路径,留空则调用django的文件上传功能 344 345 346 # 保利威视频加密服务 347 POLYV_CONFIG = { 348 "userId": "2ed6a0347e", 349 "secretkey": "ubWpbwKsi8", 350 "servicesUrl": "https://hls.videocc.net/service/v1/token", 351 } 352 353 354 # 支付宝电脑网站支付配置信息 355 ALIPAY_APPID = "2016093000628296" # 应用ID (APPID:2016093000628296) 356 APP_NOTIFY_URL = None # 应用回调地址[支付成功以后,支付宝返回结果到哪一个地址下面] 357 ALIPAY_DEBUG = True # APIPAY_GATEWAY="https://openapi.alipay.com/gateway.do" 358 359 APIPAY_GATEWAY="https://openapi.alipaydev.com/gateway.do" 360 ALIPAY_RETURN_URL = "http://www.luffycity.cn:8080/success" 361 ALIPAY_NOTIFY_URL = "http://api.luffycity.cn:8000/payments/success" 362 363 364 365 366 367 # print("BASE_DIR 的路径:", BASE_DIR) 368 # # BASE_DIR 的路径: /home/moluo/Desktop/Typory笔记/day84/luffy/luffy 369 # 370 # print("os.path.dirname(BASE_DIR) 的路径:", os.path.dirname(BASE_DIR)) 371 # # os.path.dirname(BASE_DIR) 的路径: /home/moluo/Desktop/Typory笔记/day84/luffy 372 # 373 # print("STATIC_ROOT 的路径:", STATIC_ROOT) 374 # # STATIC_ROOT 的路径: /home/moluo/Desktop/Typory笔记/day84/luffy/static
urls.py
1 """luffy URL Configuration 2 3 The `urlpatterns` list routes URLs to views. For more information please see: 4 https://docs.djangoproject.com/en/2.2/topics/http/urls/ 5 Examples: 6 Function views 7 1. Add an import: from my_app import views 8 2. Add a URL to urlpatterns: path(\'\', views.home, name=\'home\') 9 Class-based views 10 1. Add an import: from other_app.views import Home 11 2. Add a URL to urlpatterns: path(\'\', Home.as_view(), name=\'home\') 12 Including another URLconf 13 1. Import the include() function: from django.urls import include, path 14 2. Add a URL to urlpatterns: path(\'blog/\', include(\'blog.urls\')) 15 """ 16 from django.contrib import admin 17 from django.urls import path,include 18 19 import xadmin 20 xadmin.autodiscover() 21 22 # version模块自动注册需要版本控制的 Model 23 from xadmin.plugins import xversion 24 xversion.register_models() 25 26 from django.urls import re_path 27 from django.conf import settings 28 from django.views.static import serve 29 30 urlpatterns = [ 31 # path(\'admin/\', admin.site.urls), 32 path(r\'xadmin/\', xadmin.site.urls), 33 # 提供上传文件的浏览服务 34 re_path(r\'media/(?P<path>.*)\', serve, {"document_root": settings.MEDIA_ROOT}), 35 path(r\'ckeditor/\', include(\'ckeditor_uploader.urls\')), 36 path(\'\', include("home.urls")), 37 path(\'users/\', include("users.urls")), 38 path(\'courses/\', include("courses.urls")), 39 path(\'carts/\', include("cart.urls")), 40 path(\'orders/\', include("orders.urls")), 41 path(\'coupon/\', include("coupon.urls")), 42 path(\'payments/\', include("payments.urls")
1 """luffy URL Configuration 2 3 The `urlpatterns` list routes URLs to views. For more information please see: 4 https://docs.djangoproject.com/en/2.2/topics/http/urls/ 5 Examples: 6 Function views 7 1. Add an import: from my_app import views 8 2. Add a URL to urlpatterns: path(\'\', views.home, name=\'home\') 9 Class-based views 10 1. Add an import: from other_app.views import Home 11 2. Add a URL to urlpatterns: path(\'\', Home.as_view(), name=\'home\') 12 Including another URLconf 13 1. Import the include() function: from django.urls import include, path 14 2. Add a URL to urlpatterns: path(\'blog/\', include(\'blog.urls\')) 15 """ 16 17 from django.urls import re_path, path, include 18 from django.conf import settings 19 from django.views.static import serve 20 21 import xadmin 22 xadmin.autodiscover() 23 24 # version模块自动注册需要版本控制的 Model 25 from xadmin.plugins import xversion 26 xversion.register_models() 27 28 29 urlpatterns = [ 30 # path(\'admin/\', admin.site.urls), 31 path(r\'xadmin/\', xadmin.site.urls), 32 re_path(r\'media/(?P<path>.*)\', serve, {"document_root": settings.MEDIA_ROOT}), 33 path(r\'ckeditor/\', include(\'ckeditor_uploader.urls\')), 34 path(\'\', include("home.urls")), 35 path(\'users/\', include("users.urls")), 36 path(\'courses/\', include("courses.urls")), 37 path(\'carts/\', include("cart.urls")), 38 path(\'orders/\', include("orders.urls")), 39 path(\'coupon/\', include("coupon.urls")), 40 path(\'payments/\', include("payments.urls")), 41 42 ]
wsgi.py
1 """ 2 WSGI config for luffy project. 3 4 It exposes the WSGI callable as a module-level variable named ``application``. 5 6 For more information on this file, see 7 https://docs.djangoproject.com/en/2.2/howto/deployment/wsgi/ 8 """ 9 10 import os 11 12 from django.core.wsgi import get_wsgi_application 13 14 # os.environ.setdefault(\'DJANGO_SETTINGS_MODULE\', \'luffy.settings\') 15 os.environ.setdefault(\'DJANGO_SETTINGS_MODULE\', \'luffy.settings.prop\') 16 17 application = get_wsgi_application()
manage.py
1 #!/usr/bin/env python 2 """Django\'s command-line utility for administrative tasks.""" 3 import os 4 import sys 5 6 7 def main(): 8 os.environ.setdefault(\'DJANGO_SETTINGS_MODULE\', \'luffy.settings.prop\') 9 try: 10 from django.core.management import execute_from_command_line 11 except ImportError as exc: 12 raise ImportError( 13 "Couldn\'t import Django. Are you sure it\'s installed and " 14 "available on your PYTHONPATH environment variable? Did you " 15 "forget to activate a virtual environment?" 16 ) from exc 17 execute_from_command_line(sys.argv) 18 19 20 if __name__ == \'__main__\': 21 main()
pro/pro/utils/公共模型
model.py
1 from django.db import models 2 3 4 class BaseModel(models.Model): 5 """公共字段模型""" 6 orders = models.IntegerField(verbose_name=\'显示顺序\', null=True, blank=True) 7 8 is_show = models.BooleanField(verbose_name="是否上架", default=False) 9 10 is_delete = models.BooleanField(verbose_name="逻辑删除", default=False) 11 12 create_time = models.DateTimeField(auto_now_add=True, verbose_name="添加时间") 13 14 update_time = models.DateTimeField(auto_now=True, verbose_name="更新时间") 15 16 class Meta: 17 # 设置当前模型在数据迁移的时候不要为它创建表 18 abstract = True
exceptions.py
1 from rest_framework.views import exception_handler 2 3 from django.db import DatabaseError 4 from rest_framework.response import Response 5 from rest_framework import status 6 7 import logging 8 logger = logging.getLogger(\'luffy\') 9 10 def custom_exception_handler(exc, context): 11 """ 12 自定义异常处理 13 :param exc: 异常类 14 :param context: 抛出异常的上下文 15 :return: Response 响应对象 16 """ 17 # 调用drf框架原声的异常处理方法 18 response = exception_handler(exc, context) 19 20 if response is None: 21 view = context[\'view\'] 22 if isinstance(exc, DatabaseError): 23 # 数据库异常 24 logger.error(\'[%s] %s\' % (view, exc)) 25 response = Response({\'message\': \'服务器内部错误\'}, status=status.HTTP_507_INSUFFICIENT_STORAGE) 26 27 return response
home模块
adminx.py
1 import xadmin 2 from xadmin import views 3 4 5 class BaseSetting(object): 6 """xadmin的基本配置""" 7 enable_themes = True # 开启主题切换功能 8 use_bootswatch = True 9 10 11 # ### 12 13 14 xadmin.site.register(views.BaseAdminView, BaseSetting) 15 16 17 class GlobalSettings(object): 18 """xadmin的全局配置""" 19 site_title = "路飞学城" # 设置站点标题 20 site_footer = "路飞学城有限公司" # 设置站点的页脚 21 menu_style = "accordion" # 设置菜单折叠 22 23 24 xadmin.site.register(views.CommAdminView, GlobalSettings) 25 26 # 轮播图 27 from .models import BannerInfo 28 29 30 class BannerInfoModelAdmin(object): 31 list_display = ["name", "orders", "is_show"] 32 33 34 xadmin.site.register(BannerInfo, BannerInfoModelAdmin) 35 36 37 # 导航 38 from home.models import NavInfo 39 40 41 class NavInfoInfoModelAdmin(object): 42 list_display = ["name", "link", "is_show"] 43 44 45 xadmin.site.register(NavInfo, NavInfoInfoModelAdmin)
__init__.py
1 default_app_config = "home.apps.HomeConfig"
apps.py
1 from django.apps import AppConfig 2 3 4 class HomeConfig(AppConfig): 5 name = \'home\' 6 verbose_name = \'我的首页\'
models.py
1 from django.db import models 2 from luffy.utils.models import BaseModel 3 # Create your models here. 4 5 6 class BannerInfo(BaseModel): 7 """ 8 轮播图 9 """ 10 # upload_to 存储子目录,真实存放地址会使用配置中的MADIE_ROOT+upload_to 11 image = models.ImageField(upload_to=\'banner\', verbose_name=\'轮播图\', null=True,blank=True) 12 name = models.CharField(max_length=150, verbose_name=\'轮播图名称\') 13 note = models.CharField(max_length=150, verbose_name=\'备注信息\') 14 link = models.CharField(max_length=150, verbose_name=\'轮播图广告地址\') 15 16 class Meta: 17 db_table = \'ly_banner\' 18 verbose_name = \'轮播图\' 19 verbose_name_plural = verbose_name 20 21 def __str__(self): 22 return self.name 23 24 25 class NavInfo(BaseModel): 26 """ 27 导航 28 """ 29 NAV_POSITION = ( 30 (0, \'top\'), 31 (1, \'footer\') 32 ) 33 34 name = models.CharField(max_length=50, verbose_name=\'导航名称\') 35 link = models.CharField(max_length=250, verbose_name=\'导航地址\') 36 opt = models.SmallIntegerField(choices=NAV_POSITION, default=0, verbose_name=\'位置\') 37 38 class Meta: 39 db_table = \'ly_nav\' 40 verbose_name = \'导航\' 41 verbose_name_plural = verbose_name 42 43 def __str__(self): 44 return self.name
Serializer.py
1 from rest_framework.serializers import ModelSerializer 2 from .models import BannerInfo 3 4 5 class BannerInfoSerializer(ModelSerializer): 6 """轮播图序列化器""" 7 8 class Meta: 9 model = BannerInfo 10 fields = ("image", "link") 11 12 13 from rest_framework.serializers import ModelSerializer 14 from .models import NavInfo 15 16 17 class NavInfoSerializer(ModelSerializer): 18 """导航序列化器""" 19 20 class Meta: 21 model = NavInfo 22 fields = ("name", "link")
urls.py
1 from django.urls import path, re_path 2 from . import views 3 urlpatterns = [ 4 path(r"banner/", views.BannerInfoListAPIView.as_view()), 5 path(r"nav/", views.NavInfoAPIView.as_view()), 6 ]
views.py
1 from django.shortcuts import render 2 3 # Create your views here. 4 from rest_framework.generics import ListAPIView 5 from django.db.models import Q 6 from .models import BannerInfo 7 from .serializers import BannerInfoSerializer 8 9 10 class BannerInfoListAPIView(ListAPIView): 11 """ 12 轮播图列表 13 """ 14 # queryset = BannerInfo.objects.filter(Q(is_show=True) & Q(is_delete=False)).order_by("-orders") 15 queryset = BannerInfo.objects.filter(is_show=True, is_delete=False).order_by("-orders") 16 serializer_class = BannerInfoSerializer 17 18 19 from .models import NavInfo 20 from .serializers import NavInfoSerializer 21 22 23 class NavInfoAPIView(ListAPIView): 24 """ 25 导航列表 26 """ 27 queryset = NavInfo.objects.filter(Q(is_show=True) & Q(is_delete=False) & Q(opt=0)).order_by("orders") 28 serializer_class = NavInfoSerializer
users模块
apps.py
1 from django.apps import AppConfig 2 3 4 class UsersConfig(AppConfig): 5 name = \'users\' 6 verbose_name = \'我的用户\'
models.py
1 from django.contrib.auth.models import AbstractUser 2 from django.db import models 3 4 class User(AbstractUser): 5 """用户模型类""" 6 mobile = models.CharField(max_length=11, unique=True, verbose_name=\'手机号\') 7 8 class Meta: 9 db_table = \'ly_users\' 10 verbose_name = \'用户\' 11 verbose_name_plural = verbose_name 12 13 14 from luffy.utils.models import BaseModel 15 from courses.models import Course 16 class UserCourse(BaseModel): 17 pay_choices = ( 18 (0, \'支付宝\'), 19 (1, \'微信支付\'), 20 (2, \'免费活动\'), 21 (3, \'活动赠品\'), 22 (4, \'系统赠送\'), 23 ) 24 user = models.ForeignKey(User, related_name=\'user_courses\', on_delete=models.DO_NOTHING,verbose_name="用户") 25 course = models.ForeignKey(Course, related_name=\'course_users\', on_delete=models.DO_NOTHING, verbose_name="课程") 26 buy_number = models.CharField(max_length=128, null=True, verbose_name="账单号") 27 buy_type = models.SmallIntegerField(choices=pay_choices, default=0, verbose_name="购买方式") 28 pay_time = models.DateTimeField(null=True, verbose_name="购买时间") 29 out_time = models.DateTimeField(null=True, verbose_name="过期时间") 30 31 class Meta: 32 db_table = \'ly_user_course\' 33 verbose_name = \'课程购买记录\' 34 verbose_name_plural = verbose_name
urls.py
1 from django.urls.conf import path, re_path 2 3 from rest_framework_jwt.views import obtain_jwt_token 4 5 from . import views 6 7 urlpatterns = [ 8 9 # path(r\'authorizations/\', obtain_jwt_token, name=\'authorizations\'), 10 path(r\'login/\', obtain_jwt_token), 11 path(r\'captcha/\', views.CaptchaAPIView.as_view()), 12 re_path(r\'sms/(?P<mobile>1[3-9]\d{9})/\', views.SMSAPIView.as_view()), 13 path(r\'register/\', views.UserAPIView.as_view()), 14 re_path(r\'(?P<pk>\d+)/orders/\', views.UserOrderAPIView.as_view()), 15 16 ]
utils.py
1 def jwt_response_payload_handler(token, user=None, request=None): 2 """ 3 自定义jwt认证成功返回数据 4 """ 5 return { 6 \'token\': token, 7 \'id\': user.id, 8 \'username\': user.username 9 } 10 11 12 from django.contrib.auth.backends import ModelBackend 13 from .models import User 14 from django.db.models import Q 15 import re 16 17 def get_user_by_account(account): 18 """根据账号信息获取用户模型""" 19 try: 20 """ 21 # if re.match(\'^1[3-9]\d{9}$\', account): 22 # # 手机号 23 # user = User.objects.get(mobile=account) 24 # else: 25 # # 用户名 26 # user = User.objects.get(username=account) 27 """ 28 user = User.objects.get(Q(mobile=account) | Q(username=account)) 29 30 except User.DoesNotExist: 31 user = None 32 33 return user 34 35 36 class UsernameMobileAuthBackend(ModelBackend): 37 def authenticate(self, request, username=None, password=None, **kwargs): 38 # 进行登录判断 39 user = get_user_by_account(username) 40 41 # 账号通过了还要进行密码的验证,以及判断当前站好是否是激活状态 42 if isinstance(user, User) and user.check_password(password) and self.user_can_authenticate(user): 43 return user
views.py
1 from django.shortcuts import render 2 3 # Create your views here. 4 from .serializers import UserModelSerializer 5 from rest_framework.generics import CreateAPIView 6 from .models import User 7 8 9 class UserAPIView(CreateAPIView): 10 serializer_class = UserModelSerializer 11 queryset = User.objects.all() 12 13 14 from rest_framework.views import APIView 15 from luffy.libs.geetest import GeetestLib 16 from django.conf import settings 17 import random 18 from rest_framework.response import Response 19 20 21 class CaptchaAPIView(APIView): 22 """极验验证码""" 23 gt = GeetestLib(settings.PC_GEETEST_ID, settings.PC_GEETEST_KEY) 24 25 def get(self, request): 26 """提供生成验证码的配置信息""" 27 user_id = \'%06d\' % random.randint(1, 9999) 28 status = self.gt.pre_process(user_id) 29 print(status) 30 31 # 把这两段数据不要保存在session里面, 保存到redis里面 32 request.session[self.gt.GT_STATUS_SESSION_KEY] = status 33 request.session["user_id"] = user_id 34 35 response_str = self.gt.get_response_str() 36 return Response(response_str) 37 38 def post(self, request): 39 """进行二次验证""" 40 challenge = request.data.get(self.gt.FN_CHALLENGE, \'\') 41 validate = request.data.get(self.gt.FN_VALIDATE, \'\') 42 seccode = request.data.get(self.gt.FN_SECCODE, \'\') 43 44 status = request.session.get(self.gt.GT_STATUS_SESSION_KEY) 45 user_id = request.session.get("user_id") 46 47 if status: 48 result = self.gt.success_validate(challenge, validate, seccode, user_id) 49 else: 50 result = self.gt.failback_validate(challenge, validate, seccode) 51 52 # 返回一个随机字符串,在用户登录提供数据时一并发送到后端,进行验证 53 # 后面可以使用redis保存 54 55 return Response({"message": result}) 56 57 58 from luffy.libs.yuntongxun.sms import CCP 59 from django_redis import get_redis_connection 60 61 62 class SMSAPIView(APIView): 63 # url:users/ams/(?P<mobile>1[3-9]\d{9}) 64 def get(self, request, mobile): 65 redis = get_redis_connection("sms_code") 66 # 获取短信发送间隔 67 try: 68 # interval = redis.get("%s_interval" % mobile) 69 interval = redis.get("%s_sms_code" % mobile) 70 if interval: 71 print(interval) 72 return Response({"result": "-1"}) 73 except: 74 pass 75 76 ccp = CCP() 77 sms_code = "%04d" % random.randint(1, 9999) 78 result = ccp.send_template_sms(mobile, [sms_code, 5], 1) 79 80 if not result: 81 """发送成功""" 82 # 验证码5分钟内有效 83 redis.setex("%s_sms_code" % mobile, 1 * 60, sms_code) 84 # 这里的值不重要,重要的是这个变量是否在redis被查找到 85 # redis.setex("%s_interval" % mobile, 60, 1) 86 87 return Response({"result": result}) 88 89 90 from .serializers import UserOrderModelSerializer 91 from rest_framework.generics import RetrieveAPIView 92 from rest_framework.permissions import IsAuthenticated 93 94 95 class UserOrderAPIView(RetrieveAPIView): 96 permission_classes = [IsAuthenticated] 97 serializer_class = UserOrderModelSerializer 98 queryset = User.objects.all()