富文本编辑器、激活邮箱、登陆装饰器的用法、模型管理类方法(自定义)、redis使用、celery异步提交任务
富文本编辑器
模块:
安装:pip3 install tinymce
django中settings配置:
# 富文本编辑器配置 TINYMCE_DEFAULT_CONFIG = { 'theme': 'advanced', 'width': 600, 'height': 400, }
模型表:
from tinymce.models import HTMLField
class Goods(BaseModel): '''商品通用SPU模型类''' name = models.CharField(max_length=20, verbose_name='商品SPU名称') # 富文本类型:带有格式的文本(编辑文字类型) detail = HTMLField(blank=True, verbose_name='商品详情') class Meta: db_table = 'tt_goods' verbose_name = '商品SPU' verbose_name_plural = verbose_name
激活邮件:
1.在网易邮箱注册163,2.在设置中找到客户端授权密码
3.django配置:
# 发送邮件配置 EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' # smtp服务地址 EMAIL_HOST = 'smtp.163.com' # 端口号是固定的 EMAIL_PORT = 25 #发送邮件的邮箱 EMAIL_HOST_USER = 'hyw144@163.com' #在邮箱中设置的客户端授权密码 EMAIL_HOST_PASSWORD = 'huang123' #收件人看到的发件人 EMAIL_FROM = 'python<hyw144@163.com>'
4.django发送邮件模块:
from django.core.mail import send_mail
from itsdangerous import TimedJSONWebSignatureSerializer, SignatureExpired # 加密解密模块,异常模块
5.视图类逻辑:
# 发送激活邮件,包含激活链接:http://127.0.0.1/user/active # 激活链接中需要包含用户的身份信息,并且要把身份信息进行加密,还可以进行解密:使用模块:itsdangerous # 加密用户的身份信息,生成激活token,用django秘钥作为加密数据,后面是过期时间 serializer = TimedJSONWebSignatureSerializer(settings.SECRET_KEY, 3600) info = {'confirm': user_obj.id} token = serializer.dumps(info) # 把用户信息进行加密 token = token.decode('utf8') # 把token格式转为utf8 # 发邮件 subject = '真香蔬果欢迎信息' message = "" html_message = '<h1>%s,欢迎您成为真香蔬果注册会员</h1>请点击以下链接激活用户<br/><a href="http://127.0.0.1:8000/user/active/%s">http://127.0.0.1:8000/user/active/%s</a>' % ( username, token, token) # 把html标签渲染 sender = settings.EMAIL_FROM # 发件人 receiver = [email] # 收件人 send_mail(subject, message, sender, receiver,html_message=html_message) return redirect(reverse('goods:home'))
class ActiveView(View): '''用户激活''' def get(self, request, *args, **kwargs): token = kwargs.get('token') # 进行解密,获取要激活的用户信息 serializer = TimedJSONWebSignatureSerializer(settings.SECRET_KEY, 3600) try: info = serializer.loads(token) user_id = info.get('confirm') models.User.objects.filter(id=user_id).update(is_active=1) return redirect(reverse('user:login')) except SignatureExpired as e: # 激活链接过期 return HttpResponse('激活链接已过期')
登陆装饰器:
1.路由中使用模块:from django.contrib.auth.decorators import login_required
settings配置:
# 配置登录URL地址(装饰器使用跳转url) LOGIN_URL = '/user/login'
2.使用方法:login_required(填写需要装饰视图函数)
from django.conf.urls import url from . import views from django.contrib.auth.decorators import login_required urlpatterns = [ url(r'^register/', views.RegisterView.as_view(), name='register'), url(r'^active/(?P<token>.*)$', views.ActiveView.as_view(), name='active'), url(r'^login/', views.LoginView.as_view(), name='login'), url(r'^$', login_required(views.UserView.as_view()), name='user'), url(r'^order/', login_required(views.UserOrderView.as_view()), name='order'), url(r'^address/', login_required(views.AddressView.as_view()), name='address'), ]
3.视图类中:登陆函数需要做一定调整
user = authenticate(username=username, password=password) if user is not None: # 用户名已激活 if user.is_active: # 用户已激活 # 记录用户的登陆状态 login(request, user) # 这个login函数可以把session存储起来,只需要配置好session的存储位置即可 # 获取登录后所要跳转到的地址 # 默认跳转到首页 next_url = request.GET.get('next', reverse('goods:home')) # None,这样设计原因就是登录后可以通过get请求拿到,装饰后的路由 # 跳转到首页 response = redirect(next_url) # HttpResponsePermanentRedirect # 判断是否需要记录用户名 remember = request.POST.get('remember') if remember == 'on': # 记住用户名,设置session response.set_cookie('username', username, max_age=7 * 24 * 3600) else: response.delete_cookie('username') return response else: # 用户未激活 return render(request, 'login.html', {'errmsg': '账户未激活'}) else: # 用户名或密码错误 return render(request, 'login.html', {'errmsg': '用户名或密码错误'})
模型管理类方法:
class AddressManager(models.Manager): """地址模型管理器类""" # 1. 改变原有查询的结果集:all() # 2. 封装方法:用户操作模型类对应的数据表(增删改查) def get_default_address(self, user): """获取用户的默认收货地址""" # self.model:获取self对象所在的模型类 try: address = self.model.objects.get(user=user, is_default=True) except self.model.DoesNotExist: # 不存在默认收获地址 address = None return address # Address.objects.get_default_address(user) class Address(BaseModel): '''地址模型类''' user = models.ForeignKey('User', verbose_name='所属账户') receiver = models.CharField(max_length=20, verbose_name='收件人') address = models.CharField(max_length=256, verbose_name='收件地址') postal_code = models.CharField(max_length=6, null=True, verbose_name='邮政编码') phone = models.CharField(max_length=11, verbose_name='联系电话') is_default = models.BooleanField(default=False, verbose_name='是否默认') # 自定义一个模型管理器对象 objects = AddressManager()
类视图使用(减少代码冗余):
class AddressView(View): """用户地址-信息""" def get(self, request, *args, **kwargs): # 拿到默认收货地址 user = request.user address = models.Address.objects.get_default_address(user=user) return render(request, 'user_center_site.html', {'page': 'address','address': address})
redis使用
from django_redis import get_redis_connection # django_redis操作 from redis import StrictRedis # st = StrictRedis(host='127.0.0.1:6379', port='6379', db=8) con = get_redis_connection('default') #defualt是配置 history_key = 'history_%d' % user.id # 获取用户最新浏览的五个商品id(从左边取) sku_id_list = con.lrange(history_key, 0, 4)
celery异步提交任务:
1.首先在根目录下建包celery_task,下建立tasks.py
task.py里面:
from django.core.mail import send_mail from django.conf import settings from celery import Celery import django
# 必须配备在django下运行 import os os.environ.setdefault("DJANGO_SETTINGS_MODULE", "dailyfreshs.settings") django.setup() # celery的实例对象 app = Celery('celery_task.tasks', broker='redis://127.0.0.1:6379/2') # redis端口和指定数据库 # 任务函数 @app.task def send_register_active_email(to_email, username, token): subject = '真香蔬果欢迎信息' message = "" html_message = '<h1>%s,欢迎您成为真香蔬果注册会员</h1>请点击以下链接激活用户<br/><a href="http://127.0.0.1:8000/user/active/%s">http://127.0.0.1:8000/user/active/%s</a>' % ( username, token, token) # 把html标签渲染 sender = settings.EMAIL_FROM # 发件人 receiver = [to_email] # 收件人 send_mail(subject, message, sender, receiver, html_message=html_message)
"""
# 需要加上线程(eventlet)windos
启动woker:celery -A celery_task.tasks worker -l info -P eventlet
"""
视图调用函数:
send_register_active_email.delay(email, username, token)
把需要的参数传过去即可