赞
踩
12 案例:登录_哔哩哔哩_bilibili 参考大佬的B站视频教程笔记
目录
python 快速定位问题小技巧:(traceback的使用)
- from django.utils.deprecation import MiddlewareMixin
- from django.shortcuts import HttpResponse, redirect
-
-
- class AuthMiddleware(MiddlewareMixin):
- # 项目运行前的操作请求,钩子函数
- def process_request(self, request):
- # 0.排除那些不需要登录就能访问的页面
- # request.path_info 获取当前用户请求的URL /login/
- if request.path_info in ["/login/", "/image/code/"]:
- return
-
- # 1.读取当前访问的用户的session信息,如果能读到,说明已登陆过,就可以继续向后走。
- info_dict = request.session.get("info")
- # print(info_dict)
- if info_dict:
- return
-
- # 2.没有登录过,重新回到登录页面
- return redirect('/login/')
- # 注册app中间件
- 'myapp.middleware.auth.AuthMiddleware'
1.生成html表单标签、数据校验
2.form = LoginForm(initial={'user':'xxx','password':'xxx'}) # Web页面默认值,字典类型
- # form 组件配置
- class LoginForm(BootStrapForm):
- username = forms.CharField(
- label="用户名",
- widget=forms.TextInput,
- required=True
- )
- password = forms.CharField(
- label="密码",
- widget=forms.PasswordInput(render_value=True), # 展示数据(加密点显示)
- required=True
- )
-
- code = forms.CharField(
- label="验证码",
- widget=forms.TextInput,
- required=True
- )
-
- def clean_password(self): # 密码采用md5加密
- pwd = self.cleaned_data.get("password")
- return md5(pwd)
-
数据校验视图
- def login(request):
- """ 登录 """
- if request.method == "GET":
- form = LoginForm()
- return render(request, 'login.html', {'form': form})
-
- form = LoginForm(data=request.POST)
- # form = LoginForm(initial={'user':'xxx','password':'xxx','code':'xxxx'}) # Web页面初始值
- if form.is_valid():
- # 验证成功,获取到的用户名和密码
- # {'username': 'wupeiqi', 'password': '123',"code":123}
- # 验证码的校验
- user_input_code = form.cleaned_data.pop('code')
- code = request.session.get('image_code', "")
- if code.upper() != user_input_code.upper():
- form.add_error("code", "验证码错误")
- return render(request, 'login.html', {'form': form})
- # 去数据库校验用户名和密码是否正确,获取用户对象、None
- # admin_object = models.Admin.objects.filter(username=xxx, password=xxx).first()
- admin_object = models.Admin.objects.filter(**form.cleaned_data).first()
- if not admin_object:
- form.add_error("password", "用户名或密码错误")
- # form.add_error("username", "用户名或密码错误")
- return render(request, 'login.html', {'form': form})
-
- # 用户名和密码正确
- # 网站生成随机字符串; 写到用户浏览器的cookie中;在写入到session中;
- request.session["info"] = {'id': admin_object.id, 'name': admin_object.username}
- # session可以保存7天
- request.session.set_expiry(60 * 60 * 24 * 7)
-
- return redirect("/admin/list/")
-
- return render(request, 'login.html', {'form': form})
登录页面login.html
- <div class="account">
- <h2>用户登录</h2>
- <form method="post" novalidate>
- {% csrf_token %}
- <div class="form-group">
- <label>用户名</label>
- {{ form.username }}
- <span style="color: red;">{{ form.username.errors.0 }}</span>
- </div>
- <div class="form-group">
- <label>密码</label>
- {{ form.password }}
- <span style="color: red;">{{ form.password.errors.0 }}</span>
- </div>
- <div class="form-group">
- <label>图片验证码</label>
- <div class="row">
- <div class="col-xs-7">
- {{ form.code }}
- <span style="color: red;">{{ form.code.errors.0 }}</span>
- </div>
- <div class="col-xs-5">
- <img id="image_code" src="/image/code/" style="width: 125px;">
- </div>
- </div>
- </div>
- <input type="submit" value="登 录" class="btn btn-primary">
- </form>
- </div>
- 校验数据,生成表单标签
- 使用obj直接保存数据到数据库,免去复杂的xxx.objects.create(xxx)
- 默认显示数据,对象类型
obj=xxx.objects.filter(id=1).first()
obj=xxxModelForm(instance=obj)
- 依赖于数据库的model,减少字段的定义
class Meta: model = xxx fields = ['username'] # fields = "__all__"
ModelForm组件
- class UserModelForm(BootStrapModelForm):
- name = forms.CharField(
- min_length=3,
- label="用户名",
- widget=forms.TextInput(attrs={"class": "form-control"})
- )
-
- class Meta:
- model = models.UserInfo
- fields = ["name", "password", "age", 'account', 'create_time', "gender", "depart"]
- # fields = '__all__'
数据检验与保存
- def user_model_form_add(request):
- """ 添加用户(ModelForm版本)"""
- if request.method == "GET":
- form = UserModelForm()
- return render(request, 'user_model_form_add.html', {"form": form})
-
- # 用户POST提交数据,数据校验。
- form = UserModelForm(data=request.POST)
- if form.is_valid():
- # 如果数据合法,保存到数据库
- # {'name': '123','account': Decimal('0'),'gender': 1, 'depart': <Department: IT运维部门>}
- # print(form.cleaned_data)
- form.save() # 同 models.UserInfo.objects.create(..)
- return redirect('/user/list/')
-
- # 校验失败(在页面上显示错误信息)
- return render(request, 'user_model_form_add.html', {"form": form})
用户web页面user_add.html
- <div class="container">
- <div class="panel panel-default">
- <div class="panel-heading">
- <h3 class="panel-title"> 新建用户 </h3>
- </div>
- <div class="panel-body">
- <form method="post" novalidate>
- {% csrf_token %}
-
- {% for field in form %}
- <div class="form-group">
- <label>{{ field.label }}</label>
- {{ field }}
- <span style="color: red;">{{ field.errors.0 }}</span>
- </div>
- {% endfor %}
-
- <button type="submit" class="btn btn-primary">提 交</button>
- </form>
- </div>
- </div>
- </div>
- # 写入到自己的session中(以便于后续获取验证码再进行校验)
- request.session['image_code'] = code_string
- # 给Session设置60s超时
- request.session.set_expiry(60)
- # 校验
- # 验证码的校验
- user_input_code = form.cleaned_data.pop('code')
- code = request.session.get('image_code', "")
- if code.upper() != user_input_code.upper():
- form.add_error("code", "验证码错误")
- return render(request, 'login.html', {'form': form})
保存用户登录的信息到session并设置过期时间
- # 网站生成随机字符串; 写到用户浏览器的cookie中;在写入到session中;
- request.session["info"] = {'id': admin_object.id, 'name': admin_object.username}
- # session可以保存7天
- request.session.set_expiry(60 * 60 * 24 * 7)
用户密码的加密形式(即用户输入的密码是密钥加密和MD5加密后来进行和数据库中比对)
- def md5(data_string): # SECRET_KEY + MD5 加密
- obj = hashlib.md5(settings.SECRET_KEY.encode('utf-8'))
- obj.update(data_string.encode('utf-8'))
- return obj.hexdigest()
用户注销功能的实现
- def logout(request):
- """ 注销 """
- request.session.clear() # 清除session会话信息
- return redirect('/login/')
model中的choices字段的获取
- # 在django中做的约束
- gender_choices = ((1, "男"),(2, "女"),)
- gender = models.SmallIntegerField(verbose_name="性别", choices=gender_choices)
获取方法:get_字段名_display()
- queryset = models.UserInfo.objects.all()
- for row in queryset:
- print(row.get_gender_display())
-
- # 输出男或女
-
- # [注意:row.get_gender_display在前端页面时不要加括号,django自动实现]
- # setting config
- CACHES = {
- 'default':{
- 'BACKEND':'django.core.cache.backends.locmem.LocMemCache', # 内存缓存
- 'LOCATION':'unique-snowflake',
- 'TIMEOUT':300,
- 'OPTIONS':{
- 'MAX_ENTRIES':300, # 缓存最大数据条数
- 'CULL_FREQUENCY':2, # 当缓存条数达到最大值时,删除1/x的缓存数据
- }
- }
- }
- # view
- import time
- from django.views.decorators.cache import cache_page
- @cache_page(15) # 缓存时间,多长时间缓存一次,单位s
- def test_cache(request):
- t = time.time()
- return HttpResponse('time is %s'%(t))
- import traceback
- try:
- a
- except:
- print(traceback.format_exc())
- """
- 输出
- Traceback (most recent call last):
- File "E:/desktop/my_dj/web/app/tests.py", line 6, in <module>
- a
- NameError: name 'a' is not defined
- """
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。