python的Django项目后端

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 import sys
 20 sys.path.insert(0,os.path.join(BASE_DIR,"apps"))
 21 
 22 # Quick-start development settings - unsuitable for production
 23 # See https://docs.djangoproject.com/en/2.2/howto/deployment/checklist/
 24 
 25 # SECURITY WARNING: keep the secret key used in production secret!
 26 SECRET_KEY = '!!t0^(#x0l@!pp6@^!0u5lyq+4ctyui)sxmsc4*r7644@(4uh@'
 27 
 28 # SECURITY WARNING: don't run with debug turned on in production!
 29 DEBUG = True
 30 
 31 ALLOWED_HOSTS = [
 32     'api.luffycity.cn',
 33 ]
 34 
 35 # CORS组的配置信息
 36 CORS_ORIGIN_WHITELIST = (
 37     'www.luffycity.cn:8080',
 38 )
 39 # 允许ajax跨域请求时携带cookie
 40 CORS_ALLOW_CREDENTIALS = True
 41 
 42 # Application definition
 43 
 44 INSTALLED_APPS = [
 45     'django.contrib.admin',
 46     'django.contrib.auth',
 47     'django.contrib.contenttypes',
 48     'django.contrib.sessions',
 49     'django.contrib.messages',
 50     'django.contrib.staticfiles',
 51 
 52     # cors跨域组件
 53     'corsheaders',
 54     'rest_framework',
 55 
 56     'xadmin',
 57     'crispy_forms',
 58     'reversion',
 59     'django_filters',
 60     'ckeditor',  # 富文本编辑器
 61     'ckeditor_uploader',  # 富文本编辑器上传图片模块
 62 
 63 
 64     # 子应用
 65     'home',
 66     'users',
 67     'courses',
 68     'cart',
 69     'orders',
 70     'coupon',
 71     'payments',
 72 ]
 73 
 74 MIDDLEWARE = [
 75     'corsheaders.middleware.CorsMiddleware',
 76     'django.middleware.security.SecurityMiddleware',
 77     'django.contrib.sessions.middleware.SessionMiddleware',
 78     'django.middleware.common.CommonMiddleware',
 79     'django.middleware.csrf.CsrfViewMiddleware',
 80     'django.contrib.auth.middleware.AuthenticationMiddleware',
 81     'django.contrib.messages.middleware.MessageMiddleware',
 82     'django.middleware.clickjacking.XFrameOptionsMiddleware',
 83 ]
 84 
 85 ROOT_URLCONF = 'luffy.urls'
 86 
 87 TEMPLATES = [
 88     {
 89         'BACKEND': 'django.template.backends.django.DjangoTemplates',
 90         'DIRS': [],
 91         'APP_DIRS': True,
 92         'OPTIONS': {
 93             'context_processors': [
 94                 'django.template.context_processors.debug',
 95                 'django.template.context_processors.request',
 96                 'django.contrib.auth.context_processors.auth',
 97                 'django.contrib.messages.context_processors.messages',
 98             ],
 99         },
100     },
101 ]
102 
103 WSGI_APPLICATION = 'luffy.wsgi.application'
104 
105 
106 """
107 自定义用户模型类
108 配置有两项注意的地方:
109     1. 值的格式只能接收两段写法, 必须是 '子应用目录名.模型类名'
110     2. AUTH_USER_MODEL参数的设置一定要在第一次数据库迁移之前就设置好,
111        否则后续使用可能出现未知错误。
112 """
113 AUTH_USER_MODEL = 'users.User'
114 
115 # Database
116 # https://docs.djangoproject.com/en/2.2/ref/settings/#databases
117 
118 DATABASES = {
119     # 默认数据库
120     "default": {
121         "ENGINE": "django.db.backends.mysql",
122         "HOST": "127.0.0.1",
123         "PORT": 3306,
124         "USER": "luffy_user",
125         "PASSWORD": "luffy",
126         "NAME": "luffycity",
127     }
128 }
129 
130 
131 # 缓存配置
132 CACHES = {
133     "default": {
134         "BACKEND": "django_redis.cache.RedisCache",
135         # 项目上线时,需要调整这里的路径
136         "LOCATION": "redis://127.0.0.1:6379/0",
137 
138         "OPTIONS": {
139             "CLIENT_CLASS": "django_redis.client.DefaultClient",
140         }
141     },
142 
143     # 存储登录时的极验证验证码
144     "session": {
145         "BACKEND": "django_redis.cache.RedisCache",
146         # 项目上线时,需要调整这里的路径
147         "LOCATION": "redis://127.0.0.1:6379/1",
148 
149         "OPTIONS": {
150             "CLIENT_CLASS": "django_redis.client.DefaultClient",
151         }
152     },
153 
154     # 提供存储短信验证码
155     "sms_code": {
156         "BACKEND": "django_redis.cache.RedisCache",
157         "LOCATION": "redis://127.0.0.1:6379/2",
158         "OPTIONS": {
159             "CLIENT_CLASS": "django_redis.client.DefaultClient",
160         }
161     },
162 
163     # 提供存储购物车相关信息
164     "cart": {
165         "BACKEND": "django_redis.cache.RedisCache",
166         "LOCATION": "redis://127.0.0.1:6379/3",
167         "OPTIONS": {
168             "CLIENT_CLASS": "django_redis.client.DefaultClient",
169         }
170     },
171 }
172 
173 # 设置xadmin用户登录时,登录信息session保存到redis
174 SESSION_ENGINE = "django.contrib.sessions.backends.cache"
175 SESSION_CACHE_ALIAS = "session"
176 
177 
178 # Password validation
179 # https://docs.djangoproject.com/en/2.2/ref/settings/#auth-password-validators
180 
181 AUTH_PASSWORD_VALIDATORS = [
182     {
183         'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
184     },
185     {
186         'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
187     },
188     {
189         'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
190     },
191     {
192         'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
193     },
194 ]
195 
196 
197 # Internationalization
198 # https://docs.djangoproject.com/en/2.2/topics/i18n/
199 
200 LANGUAGE_CODE = 'zh-hans'
201 
202 TIME_ZONE = 'Asia/Shanghai'
203 
204 USE_I18N = True
205 
206 USE_L10N = True
207 
208 USE_TZ = False
209 
210 
211 # Static files (CSS, JavaScript, Images)
212 # https://docs.djangoproject.com/en/2.2/howto/static-files/
213 
214 # 访问静态文件的url地址前缀
215 STATIC_URL = '/static/'
216 
217 # 设置django的静态文件目录
218 STATICFILES_DIRS = [
219     os.path.join(BASE_DIR,"luffy/statics")
220 ]
221 
222 # 项目中存储上传文件的根目录[暂时配置],注意,static目录需要手动创建否则上传文件时报错
223 MEDIA_ROOT=os.path.join(BASE_DIR,"luffy/statics")
224 # 访问上传文件的url地址前缀
225 MEDIA_URL ="/media/"
226 
227 # 日志配置
228 LOGGING = {
229     'version': 1,
230     'disable_existing_loggers': False,
231     'formatters': {
232         'verbose': {
233             'format': '%(levelname)s %(asctime)s %(module)s %(lineno)d %(message)s'
234         },
235         'simple': {
236             'format': '%(levelname)s %(module)s %(lineno)d %(message)s'
237         },
238     },
239     'filters': {
240         'require_debug_true': {
241             '()': 'django.utils.log.RequireDebugTrue',
242         },
243     },
244     'handlers': {
245         'console': {
246             'level': 'DEBUG',
247             'filters': ['require_debug_true'],
248             'class': 'logging.StreamHandler',
249             'formatter': 'simple'
250         },
251         'file': {
252             'level': 'INFO',
253             'class': 'logging.handlers.RotatingFileHandler',
254             # 日志位置,日志文件名,日志保存目录必须手动创建
255             'filename': os.path.join(os.path.dirname(BASE_DIR), "logs/luffy.log"),
256             # 日志文件的最大值,这里我们设置300M
257             'maxBytes': 300 * 1024 * 1024,
258             # 日志文件的数量,设置最大日志数量为10
259             'backupCount': 10,
260             # 日志格式:详细格式
261             'formatter': 'verbose'
262         },
263     },
264     # 日志对象
265     'loggers': {
266         'django': {
267             'handlers': ['console', 'file'],
268             'propagate': True, # 是否让日志信息继续冒泡给其他的日志处理系统
269         },
270     }
271 }
272 
273 
274 REST_FRAMEWORK = {
275     # 异常处理
276     'EXCEPTION_HANDLER': 'luffy.utils.exceptions.custom_exception_handler',
277     # 配置用户认证方式
278     'DEFAULT_AUTHENTICATION_CLASSES': (
279         'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
280         'rest_framework.authentication.SessionAuthentication',
281         'rest_framework.authentication.BasicAuthentication',
282     ),
283 }
284 
285 import datetime
286 JWT_AUTH = {
287     # 配置jwt的有效期
288     'JWT_EXPIRATION_DELTA': datetime.timedelta(days=1),
289     # 设置jwt登录视图的返回值
290     'JWT_RESPONSE_PAYLOAD_HANDLER': 'users.utils.jwt_response_payload_handler',
291 }
292 
293 # 配置django的认证类功能,增加手机号登录
294 AUTHENTICATION_BACKENDS = [
295     'users.utils.UsernameMobileAuthBackend',
296 ]
297 
298 # 极验验证码配置
299 PC_GEETEST_ID = '5f4ab1914455506edffaffd4da37fea5'
300 PC_GEETEST_KEY ='460e13a49d687e5e44e25c383f0473a6'
301 
302 
303 # 短信配置
304 # 主账号
305 SMS_ACCOUNTSID = '8a216da86ab0b4d2016ab3e05fe400b1'
306 
307 # 主账号Token
308 SMS_ACCOUNTTOKEN = '5f0ba4296bbb4e248aa77253ccfe0b31'
309 
310 # 创建应用的APPID
311 SMS_APPID = '8a216da86ab0b4d2016ab3e0603900b7'
312 
313 # 说明:请求地址,生产环境配置成app.cloopen.com
314 SMS_SERVERIP = 'sandboxapp.cloopen.com'
315 
316 
317 # 富文本编辑器ckeditor配置
318 CKEDITOR_CONFIGS = {
319     'default': {
320         'toolbar': 'full',  # 工具条功能
321         'height': 300,      # 编辑器高度
322         # 'width': 300,     # 编辑器宽
323         'language':'zh-hans',
324     },
325 }
326 CKEDITOR_UPLOAD_PATH = ''  # 上传图片保存路径,留空则调用django的文件上传功能
327 
328 
329 # 保利威视频加密服务
330 POLYV_CONFIG = {
331     "userId":"62dc475e3f",
332     "secretkey":"h6FiaEBRMU",
333     "servicesUrl":"https://hls.videocc.net/service/v1/token",
334 }
335 
336 
337 
338 # 支付宝电脑网站支付配置信息
339 ALIPAY_APPID = "2016091600523592"
340 APP_NOTIFY_URL = None
341 ALIPAY_DEBUG = True
342 # APIPAY_GATEWAY="https://openapi.alipay.com/gateway.do"
343 APIPAY_GATEWAY="https://openapi.alipaydev.com/gateway.do"
344 ALIPAY_RETURN_URL = "http://www.luffycity.cn:8080/success"
345 ALIPAY_NOTIFY_URL = "http://api.luffycity.cn:8000/payments/success"
dev.py

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")),
43 ]
urls.py总路由

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 
16 application = get_wsgi_application()
wsgi.py

pro/pro/utils/公共模型

model.py

 1 from django.db import models
 2 
 3 class BaseModel(models.Model):
 4     """公共字段模型"""
 5     orders = models.IntegerField(null=True, blank=True, verbose_name='显示顺序')
 6     is_show=models.BooleanField(verbose_name="是否上架",default=False)
 7     is_delete=models.BooleanField(verbose_name="逻辑删除",default=False)
 8     create_time = models.DateTimeField(auto_now_add=True,verbose_name="添加时间")
 9     update_time = models.DateTimeField(auto_now=True,verbose_name="更新时间")
10 
11     class Meta:
12         # 设置当前模型在数据迁移的时候不要为它创建表
13         abstract = True
utils/models.py

exceptions.py

 1 from rest_framework.views import exception_handler
 2 from django.db import DatabaseError
 3 from rest_framework.response import Response
 4 from rest_framework import status
 5 
 6 import logging
 7 logger = logging.getLogger('django')
 8 
 9 def custom_exception_handler(exc, context):
10     """
11     自定义异常处理
12     :param exc: 异常对象
13     :param context: 抛出异常的上下文环境[异常发生时的相关信息,变量,函数,文件名,模块名]
14     :return: Response响应对象
15     """
16     # 调用drf框架原生的异常处理方法
17     response = exception_handler(exc, context)
18 
19     # 获取异常发生时的视图对象
20     view = context['view']
21 
22     if response is None:
23 
24         # 判断是否是数据库操作异常
25         if isinstance( exc, DatabaseError ):
26             logger.error( '[%s] %s' % (view, exc) )
27             response = Response({'message': '服务器内部错误'}, status=status.HTTP_507_INSUFFICIENT_STORAGE)
28 
29     return response
utils/exceptions.py异常处理

home模块

adminx.py

 1 import xadmin
 2 from xadmin import views
 3 
 4 class BaseSetting(object):
 5     """xadmin的基本配置"""
 6     enable_themes = True  # 开启主题切换功能
 7     use_bootswatch = True
 8 
 9 xadmin.site.register(views.BaseAdminView, BaseSetting)
10 
11 class GlobalSettings(object):
12     """xadmin的全局配置"""
13     site_title = "路飞学城"  # 设置站点标题
14     site_footer = "路飞学城有限公司"  # 设置站点的页脚
15     menu_style = "accordion"  # 设置菜单折叠
16 
17 xadmin.site.register(views.CommAdminView, GlobalSettings)
18 
19 
20 
21 # 轮播图
22 from .models import BannerInfo
23 class BannerInfoModelAdmin(object):
24     list_display=["name","orders","is_show"]
25 xadmin.site.register(BannerInfo, BannerInfoModelAdmin)
26 
27 
28 # 导航
29 from home.models import NavInfo
30 class NavInfoInfoModelAdmin(object):
31     list_display=["name","link","is_show"]
32 xadmin.site.register(NavInfo, NavInfoInfoModelAdmin)
apps/home/adminx.py

apps.py

1 from django.apps import AppConfig
2 
3 
4 class HomeConfig(AppConfig):
5     name = 'home'
6     verbose_name = '我的首页'
apps/home/apps.py

models.py

 1 from django.db import models
 2 from luffy.utils.models import BaseModel
 3 # Create your models here.
 4 class BannerInfo(BaseModel):
 5     """
 6     轮播图
 7     """
 8     # upload_to 存储子目录,真实存放地址会使用配置中的MADIE_ROOT+upload_to
 9     image = models.ImageField(upload_to='banner', verbose_name='轮播图', null=True,blank=True)
10     name = models.CharField(max_length=150, verbose_name='轮播图名称')
11     note = models.CharField(max_length=150, verbose_name='备注信息')
12     link = models.CharField(max_length=150, verbose_name='轮播图广告地址')
13 
14     class Meta:
15         db_table = 'ly_banner'
16         verbose_name = '轮播图'
17         verbose_name_plural = verbose_name
18 
19     def __str__(self):
20         return self.name
21 
22 
23 class NavInfo(BaseModel):
24     """
25     导航
26     """
27     NAV_POSITION = (
28         (0, 'top'),
29         (1, 'footer')
30     )
31 
32     name = models.CharField(max_length=50, verbose_name='导航名称')
33     link = models.CharField(max_length=250, verbose_name='导航地址')
34     opt = models.SmallIntegerField(choices=NAV_POSITION, default=0, verbose_name='位置')
35 
36     class Meta:
37         db_table = 'ly_nav'
38         verbose_name = '导航'
39         verbose_name_plural = verbose_name
40 
41     def __str__(self):
42         return self.name
apps/home/models.py

Serializer.py

 1 from rest_framework.serializers import ModelSerializer
 2 from .models import BannerInfo
 3 class BannerInfoSerializer(ModelSerializer):
 4     """轮播图序列化器"""
 5     class Meta:
 6         model=BannerInfo
 7         fields = ("image","link")
 8 
 9 
10 from rest_framework.serializers import ModelSerializer
11 from .models import NavInfo
12 class NavInfoSerializer(ModelSerializer):
13     """导航序列化器"""
14     class Meta:
15         model=NavInfo
16         fields = ("name","link")
apps/home/serializer.py

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 ]
apps/home/urls.py

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 class BannerInfoListAPIView(ListAPIView):
 9     """
10     轮播图列表
11     """
12     # queryset = BannerInfo.objects.filter(Q(is_show=True) & Q(is_delete=False)).order_by("-orders")
13     queryset = BannerInfo.objects.filter( is_show=True, is_delete=False ).order_by("-orders")
14     serializer_class = BannerInfoSerializer
15 
16 
17 
18 from .models import NavInfo
19 from .serializers import NavInfoSerializer
20 class NavInfoAPIView(ListAPIView):
21     """
22     导航列表
23     """
24     queryset = NavInfo.objects.filter( Q(is_show=True) & Q(is_delete=False) & Q(opt=0) ).order_by("orders")
25     serializer_class = NavInfoSerializer
apps/home/apps.py

user模块

apps.py

1 from django.apps import AppConfig
2 
3 
4 class UsersConfig(AppConfig):
5     name = 'users'
apps/users/apps.py

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
apps/users/models.py

urls.py

 1 from django.urls.conf import path,re_path
 2 from rest_framework_jwt.views import obtain_jwt_token
 3 from . import views
 4 urlpatterns = [
 5     path(r'login/', obtain_jwt_token ),
 6     path(r'register/', views.UserAPIView.as_view() ),
 7     path(r'captcha/', views.CaptchaAPIView.as_view() ),
 8     re_path(r'sms/(?P<mobile>1[3-9]\d{9})/', views.SMSAPIView.as_view() ),
 9     re_path(r'(?P<pk>\d+)/orders/',views.UserOrderAPIView.as_view()),
10 ]
apps/users/models.py

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 from django.contrib.auth.backends import ModelBackend
12 from .models import User
13 from django.db.models import Q
14 import re
15 
16 def get_user_by_account(account):
17     """根据账号信息获取用户模型"""
18     try:
19         # if re.match('^1[3-9]\d{9}$', account):
20         #     # 手机号
21         #     user = User.objects.get(mobile=account)
22         # else:
23         #     # 用户名
24         #     user = User.objects.get(username=account)
25 
26         user = User.objects.get(Q(mobile=account) | Q(username=account))
27 
28     except User.DoesNotExist:
29 
30         user = None
31 
32     return user
33 
34 
35 class UsernameMobileAuthBackend(ModelBackend):
36     def authenticate(self, request, username=None, password=None, **kwargs):
37         # 进行登录判断
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
apps/users/utils.py

views.py

 1 from rest_framework.views import APIView
 2 from luffy.libs.geetest import GeetestLib
 3 from django.conf import settings
 4 import random
 5 from rest_framework.response import Response
 6 from django_redis import get_redis_connection
 7 
 8 class CaptchaAPIView(APIView):
 9     """极验验证码"""
10     gt = GeetestLib(settings.PC_GEETEST_ID, settings.PC_GEETEST_KEY)
11     redis = get_redis_connection("default")
12     def get(self,request):
13         """提供生成验证码的配置信息"""
14         user_id = '%06d' % random.randint(1, 9999)
15         status = self.gt.pre_process(user_id)
16 
17         # 把这两段数据不要保存在session里面, 保存到redis里面
18         # request.session[self.gt.GT_STATUS_SESSION_KEY] = status
19         # request.session["user_id"] = user_id
20         # 使用django-redis保存流水号和用户标识符
21 
22 
23         # set(键,值)         设置一个字符串值
24         # setex(键,有效期,值) 设置一个指定有效期的字符串值
25         self.redis.setex(self.gt.GT_STATUS_SESSION_KEY, 10*60, status)
26         self.redis.setex("user_id", 10*60, user_id)
27 
28         response_str = self.gt.get_response_str()
29         return Response(response_str)
30 
31     def post(self,request):
32         """进行二次验证"""
33         challenge = request.data.get(self.gt.FN_CHALLENGE, '')
34         validate = request.data.get(self.gt.FN_VALIDATE, '')
35         seccode = request.data.get(self.gt.FN_SECCODE, '')
36 
37         # status = request.session.get(self.gt.GT_STATUS_SESSION_KEY)
38         # user_id = request.session.get("user_id")
39         # 从redis中获取流水号和用户标识符
40         status = self.redis.get(self.gt.GT_STATUS_SESSION_KEY)
41         user_id = self.redis.get("user_id")
42 
43         if status:
44             result = self.gt.success_validate(challenge, validate, seccode, user_id)
45         else:
46             result = self.gt.failback_validate(challenge, validate, seccode)
47 
48         # todo 返回一个随机字符串,在用户登录提供数据时一并发送到后端,进行验证
49 
50         # 后面可以使用redis保存
51 
52         return Response({"message": result})
53 
54 from luffy.libs.yuntongxun.sms import CCP
55 from django_redis import get_redis_connection
56 class SMSAPIView(APIView):
57     # url: users/sms/(?P<mobile>1[3-9]\d{9})
58     def get(self,request,mobile):
59         redis = get_redis_connection("sms_code")
60         # 获取短信发送间隔
61         try:
62             interval = redis.get("%s_interval" % mobile)
63             if interval:
64                 print(interval)
65                 return Response({"result":"-1"})
66         except:
67             pass
68 
69         ccp = CCP()
70         sms_code = "%04d" % random.randint(1,9999)
71         result = ccp.send_template_sms(mobile,[sms_code, 5],1)
72 
73         if not result:
74             """发送成功"""
75 
76             redis.setex("%s_sms_code" % mobile, 5*60, sms_code)
77             # 这里的值不重要,重要的是这个变量是否在redis被查找到
78             redis.setex("%s_interval" % mobile, 60, 1)
79 
80         return Response({"result":result})
81 
82 
83 from .serializers import UserModelSerializer
84 from rest_framework.generics import CreateAPIView
85 from .models import User
86 class UserAPIView(CreateAPIView):
87     serializer_class = UserModelSerializer
88     queryset = User.objects.all()
89 
90 from .serializers import UserOrderModelSerializer
91 from rest_framework.generics import RetrieveAPIView
92 from rest_framework.permissions import IsAuthenticated
93 class UserOrderAPIView(RetrieveAPIView):
94     permission_classes = [IsAuthenticated]
95     serializer_class = UserOrderModelSerializer
96     queryset = User.objects.all()
apps/users/views.py

猜你喜欢

转载自www.cnblogs.com/zhongmin/p/11286161.html