zhongmin

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()

 

分类:

技术点:

相关文章: