当前位置:   article > 正文

Django前后端分离之后端基础3

Django前后端分离之后端基础3

12 案例:登录_哔哩哔哩_bilibili   参考大佬的B站视频教程笔记


目录

登录接口的实现会话机制成功后的信息保存:

中间件的使用,解决登录保护使未登录过的用户进行登录

Form组件 - 主要作用:

Form组件信息的配置

ModelForm组件 - 特点:

验证码的保存在session会话中并设置过期时间

缓存的使用

python 快速定位问题小技巧:(traceback的使用)


登录接口的实现会话机制成功后的信息保存:
  1. 生成随机字符串
  2. 返回到用户的浏览器的cookie中
  3. 存储到网站的session中  随机字符串+用户标识
中间件的使用,解决登录保护使未登录过的用户进行登录
  1. from django.utils.deprecation import MiddlewareMixin
  2. from django.shortcuts import HttpResponse, redirect
  3. class AuthMiddleware(MiddlewareMixin):
  4. # 项目运行前的操作请求,钩子函数
  5. def process_request(self, request):
  6. # 0.排除那些不需要登录就能访问的页面
  7. # request.path_info 获取当前用户请求的URL /login/
  8. if request.path_info in ["/login/", "/image/code/"]:
  9. return
  10. # 1.读取当前访问的用户的session信息,如果能读到,说明已登陆过,就可以继续向后走。
  11. info_dict = request.session.get("info")
  12. # print(info_dict)
  13. if info_dict:
  14. return
  15. # 2.没有登录过,重新回到登录页面
  16. return redirect('/login/')
  1. # 注册app中间件
  2. 'myapp.middleware.auth.AuthMiddleware'
Form组件 - 主要作用:

1.生成html表单标签、数据校验

2.form = LoginForm(initial={'user':'xxx','password':'xxx'}) # Web页面默认值,字典类型

Form组件信息的配置
  1. # form 组件配置
  2. class LoginForm(BootStrapForm):
  3. username = forms.CharField(
  4. label="用户名",
  5. widget=forms.TextInput,
  6. required=True
  7. )
  8. password = forms.CharField(
  9. label="密码",
  10. widget=forms.PasswordInput(render_value=True), # 展示数据(加密点显示)
  11. required=True
  12. )
  13. code = forms.CharField(
  14. label="验证码",
  15. widget=forms.TextInput,
  16. required=True
  17. )
  18. def clean_password(self): # 密码采用md5加密
  19. pwd = self.cleaned_data.get("password")
  20. return md5(pwd)

数据校验视图

  1. def login(request):
  2. """ 登录 """
  3. if request.method == "GET":
  4. form = LoginForm()
  5. return render(request, 'login.html', {'form': form})
  6. form = LoginForm(data=request.POST)
  7. # form = LoginForm(initial={'user':'xxx','password':'xxx','code':'xxxx'}) # Web页面初始值
  8. if form.is_valid():
  9. # 验证成功,获取到的用户名和密码
  10. # {'username': 'wupeiqi', 'password': '123',"code":123}
  11. # 验证码的校验
  12. user_input_code = form.cleaned_data.pop('code')
  13. code = request.session.get('image_code', "")
  14. if code.upper() != user_input_code.upper():
  15. form.add_error("code", "验证码错误")
  16. return render(request, 'login.html', {'form': form})
  17. # 去数据库校验用户名和密码是否正确,获取用户对象、None
  18. # admin_object = models.Admin.objects.filter(username=xxx, password=xxx).first()
  19. admin_object = models.Admin.objects.filter(**form.cleaned_data).first()
  20. if not admin_object:
  21. form.add_error("password", "用户名或密码错误")
  22. # form.add_error("username", "用户名或密码错误")
  23. return render(request, 'login.html', {'form': form})
  24. # 用户名和密码正确
  25. # 网站生成随机字符串; 写到用户浏览器的cookie中;在写入到session中;
  26. request.session["info"] = {'id': admin_object.id, 'name': admin_object.username}
  27. # session可以保存7
  28. request.session.set_expiry(60 * 60 * 24 * 7)
  29. return redirect("/admin/list/")
  30. return render(request, 'login.html', {'form': form})

登录页面login.html

  1. <div class="account">
  2. <h2>用户登录</h2>
  3. <form method="post" novalidate>
  4. {% csrf_token %}
  5. <div class="form-group">
  6. <label>用户名</label>
  7. {{ form.username }}
  8. <span style="color: red;">{{ form.username.errors.0 }}</span>
  9. </div>
  10. <div class="form-group">
  11. <label>密码</label>
  12. {{ form.password }}
  13. <span style="color: red;">{{ form.password.errors.0 }}</span>
  14. </div>
  15. <div class="form-group">
  16. <label>图片验证码</label>
  17. <div class="row">
  18. <div class="col-xs-7">
  19. {{ form.code }}
  20. <span style="color: red;">{{ form.code.errors.0 }}</span>
  21. </div>
  22. <div class="col-xs-5">
  23. <img id="image_code" src="/image/code/" style="width: 125px;">
  24. </div>
  25. </div>
  26. </div>
  27. <input type="submit" value="登 录" class="btn btn-primary">
  28. </form>
  29. </div>
ModelForm组件 - 特点:
  1. 校验数据,生成表单标签
  2. 使用obj直接保存数据到数据库,免去复杂的xxx.objects.create(xxx)
  3. 默认显示数据,对象类型

        obj=xxx.objects.filter(id=1).first()   

        obj=xxxModelForm(instance=obj)

  1. 依赖于数据库的model,减少字段的定义
    class Meta:
        model = xxx
        fields = ['username']
        # fields = "__all__"

 ModelForm组件

  1. class UserModelForm(BootStrapModelForm):
  2. name = forms.CharField(
  3. min_length=3,
  4. label="用户名",
  5. widget=forms.TextInput(attrs={"class": "form-control"})
  6. )
  7. class Meta:
  8. model = models.UserInfo
  9. fields = ["name", "password", "age", 'account', 'create_time', "gender", "depart"]
  10. # fields = '__all__'

数据检验与保存

  1. def user_model_form_add(request):
  2. """ 添加用户(ModelForm版本)"""
  3. if request.method == "GET":
  4. form = UserModelForm()
  5. return render(request, 'user_model_form_add.html', {"form": form})
  6. # 用户POST提交数据,数据校验。
  7. form = UserModelForm(data=request.POST)
  8. if form.is_valid():
  9. # 如果数据合法,保存到数据库
  10. # {'name': '123','account': Decimal('0'),'gender': 1, 'depart': <Department: IT运维部门>}
  11. # print(form.cleaned_data)
  12. form.save() # 同 models.UserInfo.objects.create(..)
  13. return redirect('/user/list/')
  14. # 校验失败(在页面上显示错误信息)
  15. return render(request, 'user_model_form_add.html', {"form": form})

 用户web页面user_add.html

  1. <div class="container">
  2. <div class="panel panel-default">
  3. <div class="panel-heading">
  4. <h3 class="panel-title"> 新建用户 </h3>
  5. </div>
  6. <div class="panel-body">
  7. <form method="post" novalidate>
  8. {% csrf_token %}
  9. {% for field in form %}
  10. <div class="form-group">
  11. <label>{{ field.label }}</label>
  12. {{ field }}
  13. <span style="color: red;">{{ field.errors.0 }}</span>
  14. </div>
  15. {% endfor %}
  16. <button type="submit" class="btn btn-primary">提 交</button>
  17. </form>
  18. </div>
  19. </div>
  20. </div>
验证码的保存在session会话中并设置过期时间
  1. # 写入到自己的session中(以便于后续获取验证码再进行校验)
  2. request.session['image_code'] = code_string
  3. # 给Session设置60s超时
  4. request.session.set_expiry(60)
  1. # 校验
  2. # 验证码的校验
  3. user_input_code = form.cleaned_data.pop('code')
  4. code = request.session.get('image_code', "")
  5. if code.upper() != user_input_code.upper():
  6. form.add_error("code", "验证码错误")
  7. return render(request, 'login.html', {'form': form})

保存用户登录的信息到session并设置过期时间

  1. # 网站生成随机字符串; 写到用户浏览器的cookie中;在写入到session中;
  2. request.session["info"] = {'id': admin_object.id, 'name': admin_object.username}
  3. # session可以保存7
  4. request.session.set_expiry(60 * 60 * 24 * 7)

用户密码的加密形式(即用户输入的密码是密钥加密和MD5加密后来进行和数据库中比对)

  1. def md5(data_string): # SECRET_KEY + MD5 加密
  2. obj = hashlib.md5(settings.SECRET_KEY.encode('utf-8'))
  3. obj.update(data_string.encode('utf-8'))
  4. return obj.hexdigest()

用户注销功能的实现

  1. def logout(request):
  2. """ 注销 """
  3. request.session.clear() # 清除session会话信息
  4. return redirect('/login/')

model中的choices字段的获取

  1. # 在django中做的约束
  2. gender_choices = ((1, "男"),(2, "女"),)
  3. gender = models.SmallIntegerField(verbose_name="性别", choices=gender_choices)

 获取方法:get_字段名_display() 

  1. queryset = models.UserInfo.objects.all()
  2. for row in queryset:
  3. print(row.get_gender_display())
  4. # 输出男或女
  5. # [注意:row.get_gender_display在前端页面时不要加括号,django自动实现]
缓存的使用
  • 响应头 Expires  缓存过期时间,用来指定资源到期的时间
  • 响应头 Chche Control,用于控制网页的缓存,创建后的时间缓存失效,单位s
  • get_or_set 若未获取到数据则执行set操作
  • add(key,value) 存储缓存
  • get(key) 获取缓存数据
  • set_many(dict,timeout) 批量存储缓存
  • delete(key) 删除缓存数据
  • get_many(key_list) 批量获取数据
  1. # setting config
  2. CACHES = {
  3. 'default':{
  4. 'BACKEND':'django.core.cache.backends.locmem.LocMemCache', # 内存缓存
  5. 'LOCATION':'unique-snowflake',
  6. 'TIMEOUT':300,
  7. 'OPTIONS':{
  8. 'MAX_ENTRIES':300, # 缓存最大数据条数
  9. 'CULL_FREQUENCY':2, # 当缓存条数达到最大值时,删除1/x的缓存数据
  10. }
  11. }
  12. }
  1. # view
  2. import time
  3. from django.views.decorators.cache import cache_page
  4. @cache_page(15) # 缓存时间,多长时间缓存一次,单位s
  5. def test_cache(request):
  6. t = time.time()
  7. return HttpResponse('time is %s'%(t))

 

python 快速定位问题小技巧:(traceback的使用)
  1. import traceback
  2. try:
  3. a
  4. except:
  5. print(traceback.format_exc())
  6. """
  7. 输出
  8. Traceback (most recent call last):
  9. File "E:/desktop/my_dj/web/app/tests.py", line 6, in <module>
  10. a
  11. NameError: name 'a' is not defined
  12. """

本文内容由网友自发贡献,转载请注明出处:https://www.wpsshop.cn/w/菜鸟追梦旅行/article/detail/170018
推荐阅读
相关标签
  

闽ICP备14008679号