zoukankan      html  css  js  c++  java
  • DJANGO-天天生鲜项目从0到1-002-用户模块-注册

    HTML模板配置

    1.静态文件路径设置(settings.py):

    STATIC_URL = '/static/'
    
    STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static')]

    2.html模板语言:

    for django 1.8: 

    {% load staticfiles %}

    for django 3.0:

    {% load static %}

     

    URL配置

    1.编辑项目级的url.py

    需要添加namespace,以便后续直接引用

    urlpatterns = [
    ...
    path('user/', include(('user.urls', 'user'), namespace='user')),
    ...
    ]

    注意这里给应用设置namespace时,include的第一个参数需要为一个二元组,与django1.x不同

    for django 1.x:

    url(r'^', include('home.urls', namespace='home')),

    for django 2.x and 3.x

    path('', include(('home.urls', 'home'), namespace='home'))

    2.编辑应用层url.py

    urlpatterns = [
    ...
    path('register/', RegisterView.as_view(), name='register'),
    ...
    ]

    编辑应用类视图

    通过定义类class而不是定义方法def的形式定义视图,在类中定义get和post方法处理对应的请求方式

    注意:

    1. 获取POST传过来的参数时,若前台表单字段必填,则可直接使用request.POST['key'],若表单字段非必填,则使用request.POST.get('key', default='off')

    因为request.POST返回的是一个字段dic,若'key'不在字典中,则dic['key']会抛出异常'MultiValueDictKeyError',因此使用dic.get方法处理获取不到的情况

    2. 在调用render方法时,传给模板的参数变量content定义在类视图中,该类下面的方法用到该变量时,需要在他前面加上self.引用

    3. 传给模板的content参数,若其中有赋值,如点击注册按钮时,在post中校验到数据错误,content['errmsg':'用户名重复!'],然后传给模板,这时调用get方法,重新刷新页面并把错误数据展示出来,到这一步是没有问题的,但是如果再次手动刷新页面时(会调用get方法),错误数据仍然会展示。说明手动刷新时,content[‘errmsg’]的值并没有重新置为空,原因是类视图下面定义的content只会初始化一次,并不是每次调用get或者post方式都会先进行初始化,因此需要重写__init__方法,在其中初始化content的值,每次调用get或者post时都会先调用__init__方法

     Django邮件发送

    Django中内置了邮件发送功能,被定义在django.core.mail模块中。发送邮件需要使用SMTP服务器,常用的免费服务器有:163126QQ,下面以163邮件为例。

    1.注册163邮箱itcast88,登录后设置。

    2.配置settings.py文件

    EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
    EMAIL_HOST = 'smtp.163.com'
    EMAIL_PORT = 25
    #发送邮件的邮箱
    EMAIL_HOST_USER = 'itcast88@163.com'
    #在邮箱中设置的客户端授权密码
    EMAIL_HOST_PASSWORD = 'python808'
    #收件人看到的发件人
    EMAIL_FROM = 'python<itcast88@163.com>'

    3.视图中调用send_email方法

    from django.conf import settings
    from django.core.mail import send_mail
    
    html_message = '<a href="http://http://192.168.183.129:8000/activate/1">点击激活</a>'
    send_mail(subject='this is subject', # 邮件主题
        message='this is message', # 邮件内容,会被html_message覆盖
        from_email=settings.EMAIL_FROM,
        recipient_list=['test@qq.com'],
        html_message=html_message)

     

     使用Celery异步发邮件

    1.在虚拟环境中安装celery

    pip install celery

    2.最简单的配置方法

    2.1在应用目录下创建task.py文件

    cd dailyfresh/apps/user
    tounch tasks.py

    编辑tasks.py

    from celery import Celery
    # 创建Celery实例对象(应用),第一个参数为应用名称,第二个参数为中间人broker,这里使用redis
    app = Celery('celery_app_name', broker='redis://127.0.0.1:6379/0')
    
    # 创建任务,需要装饰器@apps.task()
    @app.task()
    def test_task:
    return 1234

    2.2在view视图中调用test.task方法

    from .tasks import test_task
    
    test_task.delay()

    2.2启动worker

    启动worker的语句为:

    celery -A xxxx worker --loglevel=info

    注意:不管该命令是在什么路径下执行的,其中xxxx指向的文件中必须包含 import Celery,或者xxxx文件名就叫celery.py(即上面的tasks.py文件改名为celery.py),其他情况则会报错:‘Module 'xxxx' has no attribute 'celery'’

    例:cd至dailyfresh/apps下,运行 celery -A user worker --loglevel=info,则报错:Module 'user' has no attribute 'celery',尽管tasks.py就在user的目录下,也会导致报错

     因此xxxx必须指向导入了celery的文件如:celery -A user.tasks worker --loglevel=info

    或者将tasks.py重命名为celery.py,重新运行:celery -A user worker --loglevel=info

     

    2.3启动django项目,调用该任务,可看到worker正常执行了任务

    3.配合django自身设置或属性使用

    上述简单配置中,tasks.py中的任务只是简单的return,我们这次换成django的发送邮件任务

    from celery import Celery
    from django.conf import settings
    from django.core.mail import send_mail
    
    # 创建Celery实例对象(应用),第一个参数为应用名称,第二个参数为中间人broker,这里使用redis
    app = Celery('user', broker='redis://127.0.0.1:6379/0')
    
    # 创建任务,需要装饰器@apps.task()
    
    @app.task()
    def send_mail_task(subject, recipient_list, message=None, html_message=None):
      '''发送邮件任务'''
      send_mail(subject=subject, # 邮件主题
           message=message, # 邮件内容,会被html_message覆盖
            from_email=settings.EMAIL_FROM,
           recipient_list=recipient_list,
           html_message=html_message)

    重新启动django项目和worker,调用任务send_mail_task,发现虽然worker接收到了任务,但是处理任务的时候,报错了,意思是当处理到settings.EMAIL_FROM的时候,需要去读取django的配置文件setting.py,尽管这个配置文件已经通过 from django.conf import settings 导入了,但是celery并不能读取到这些环境信息和配置信息,所以我们需要给celery的worker单独导入django环境和配置信息

     在settings.py的同级目录下创建celery.py,编辑celery.py文件

    from __future__ import absolute_import, unicode_literals
    import os 
    from celery import Celery
    
    # 为celery设置环境变量
    os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'dailyfresh.settings')
    
    # 创建应用
    app = Celery("dailyfresh")
    
    #使用CELERY_ 作为前缀,在settings.py中写配置
    app.config_from_object('django.conf:settings', namespace='CELERY')
    
    # 设置从已经安装的app中自动加载任务
    app.autodiscover_tasks()

     编辑settings.py同级目录下的__init__.py

    from __future__ import absolute_import, unicode_literals
    from .celery import app as celery_app
    __all__ = ['celery_app']

    编辑settings.py文件,配置celery参数

    CELERY_BROKER_URL = 'redis://127.0.0.1:6379/0' # Broker配置,使用Redis作为消息中间件
    CELERY_RESULT_BACKEND = 'redis://127.0.0.1:6379/1' # BACKEND配置,这里使用redis
    CELERY_RESULT_SERIALIZER = 'json' # 结果序列化方案

    在项目根目录下启动worker

    celery -A dailyfresh worker --loglevel=info

    爆黄说明读取到了settings.py中的配置信息

     修改原tasks.py文件

    因为在上述celery.py中创建了celery的apps,因此tasks.py中直接导入即可

    from django.conf import settings
    from django.core.mail import send_mail
    from dailyfresh.celery import app
    
    @app.task()
    def send_mail_task(subject, recipient_list, message=None, html_message=None):
    '''发送邮件任务'''
    send_mail(subject=subject, # 邮件主题
        message=message, # 邮件内容,会被html_message覆盖
        from_email=settings.EMAIL_FROM,
        recipient_list=recipient_list,
        html_message=html_message)

    itsdangerous数据加密

    加密过程

    from itsdangerous import TimedJSONWebSignatureSerializer as Serializer
    # 通过itsdangerous加密user_id
    # 创建加密对象,3600秒后过期
    serializer = Serializer(settings.SECRET_KEY, 3600)
    info = {'userid': user.id} # 定义加密信息
    token = serializer.dumps(info) # 进行加密
    token = token.decode() # byte格式转为utf-8格式,默认utf-8
    send_mail_task.delay(username, email, token) #发送加密链接

    解密过程

    from itsdangerous import TimedJSONWebSignatureSerializer as Serializer
    from itsdangerous import SignatureExpired
    # 解密token 
    serializer = Serializer(settings.SECRET_KEY, 3600)
    try:
      info = serializer.loads(token)
      user_id = info['userid'] # 获取userid
      user = User.objects.get(id=user_id) # 更新数据库数据
      user.is_active = 1
      user.save()
      return redirect(reverse('user:login')) # 返回登录页面
    except SignatureExpired:
      # 链接已过期
      return HttpResponse('激活链接已过期!')
  • 相关阅读:
    11.分类与监督学习,朴素贝叶斯分类算法
    14 深度学习-卷积
    13-垃圾邮件分类2
    12.朴素贝叶斯-垃圾邮件分类
    9、主成分分析
    8、特征选择
    7.逻辑回归实践
    6.逻辑归回
    5.线性回归算法
    15 手写数字识别-小数据集
  • 原文地址:https://www.cnblogs.com/gcxblogs/p/12773598.html
Copyright © 2011-2022 走看看