forms组件

form组件能够完成的事情:
1.渲染html代码
2.检验数据
3.展示提示信息

  1. class MyForm(forms.Form):
  2. username = forms.CharField(min_length=3,max_length=8,label='用户名',
  3. error_messages={
  4. 'min_length':'用户名最少3位',
  5. 'max_length':"用户名最多8位",
  6. 'required':'用户名不能为空'
  7. }
  8. )#最小3位,最大8
  9. password = forms.CharField(min_length=3,max_length=8,label='密码',
  10. error_messages={
  11. 'min_length': '密码最少3位',
  12. 'max_length': "密码最多8位",
  13. 'required': '密码不能为空'
  14. }
  15. )
  16. email = forms.EmailField(label='邮箱'
  17. ,error_messages={
  18. 'invalid':'邮箱格式不正确',
  19. 'required':'邮箱不能为空',
  20. })#必须符合邮箱格式

测试环境(python console)

校验数据

  1. form_obj = views.MyForm({'username':'wyy','password':'123','email':'123'})
  2. form_obj.is_valid() 查看是否符合
  3. False
  4. form_obj.errors 查看不符合数据
  5. {'email': ['Enter a valid email address.']}
  6. form_obj.cleaned_data 查看符合数据
  7. {'username': 'wyy', 'password': '123'}
  8. 多传不影响校验
  9. class内默认都要传值

渲染标签

forms组件只会渲染获取用户输入的标签,不会渲染按钮

  1. 后端
  2. def index(request):
  3. form_obj = MyForm()
  4. return render(request,'index.html',locals())
  5. 前端
  6. <p>第一种渲染方式</p> 封装程度高,不利于拓展
  7. {{ form_obj.as_p }}
  8. {{ form_obj.as_ul }}
  9. {{ form_obj.as_table }}
  10. <p>第二种渲染方式</p> 可拓展性强,要写的代码多
  11. {{ form_obj.username.label }}{{ form_obj.username }}
  12. <p>第三种渲染方式</p>
  13. {% for form in form_obj %}
  14. <p>{{ form.label }}:{{ form }}</p>
  15. {% endfor %}

展示信息

  1. 后端
  2. def index(request):
  3. form_obj = MyForm()
  4. if request.method == 'POST':
  5. form_obj = MyForm(request.POST)
  6. if form_obj.is_valid():
  7. pass
  8. return render(request,'index.html',locals())
  9. 前端
  10. {% for form in form_obj %}
  11. <p>
  12. {{ form.label }}:{{ form }}
  13. <span style="color: crimson">{{ form.errors.0 }}</span>
  14. </p>
  15. {% endfor %}
  16. <input type="submit">
  17. 必备:getpost请求传给html的对象变量名必须一致
  18. 数据不合法的时候会保留数据,可以基于之前的进行修改

钩子函数(HOOK)

局部钩子:给单个字段增加检验规则时候可以使用
全部钩子:给多个字段增加检验规则时候可以使用

  1. class MyForm(forms.Form):
  2. username = forms.CharField(min_length=3,max_length=8,label='用户名',
  3. error_messages={
  4. 'min_length':'用户名最少3位',
  5. 'max_length':"用户名最多8位",
  6. 'required':'用户名不能为空'
  7. }
  8. )#最小3位,最大8
  9. password = forms.CharField(min_length=3,max_length=8,label='密码',
  10. error_messages={
  11. 'min_length': '密码最少3位',
  12. 'max_length': "密码最多8位",
  13. 'required': '密码不能为空'
  14. }
  15. )
  16. confirm_password = forms.CharField(min_length=3, max_length=8, label='确认密码',
  17. error_messages={
  18. 'min_length': '确认密码最少3位',
  19. 'max_length': "确认密码最多8位",
  20. 'required': '确认密码不能为空'
  21. }
  22. )
  23. email = forms.EmailField(label='邮箱'
  24. ,error_messages={
  25. 'invalid':'邮箱格式不正确',
  26. 'required':'邮箱不能为空',
  27. })#必须符合邮箱格式
  28. #局部钩子
  29. def clean_username(self):
  30. username = self.cleaned_data.get('username')
  31. if 'qqq' in username:
  32. #错误信息
  33. self.add_error('username','错误信息')
  34. #将钩子函数拿到的数据放回去
  35. return username
  36. #全局钩子
  37. def clean(self):
  38. password = self.cleaned_data.get('password')
  39. confirm_password = self.cleaned_data.get('confirm_password')
  40. if not password == confirm_password:
  41. self.add_error('confirm_password','两次密码不一致')
  42. return self.cleaned_data

其他参数

  1. label 字段名
  2. error_messages 自定义报错信息
  3. initial 默认值
  4. required 控制字段是否必填
  5. widget = forms.widgets.TextInput(attrs={'class':'form-control'})
  6. 正则校验
  7. from django.core.validators import RegexValidator
  8. phone= forms.CharField(
  9. validators=[RegexValidator(r'^[0-9]+$', '请输入数字'),
  10. RegexValidator(r'^159[0-9]+$', '数字必须以159开头')],
  11. )
  1. radioSelect
  2. radio值为字符串
  3. class LoginForm(forms.Form):
  4. username = forms.CharField(
  5. min_length=8,
  6. label="用户名",
  7. initial="张三",
  8. error_messages={
  9. "required": "不能为空",
  10. "invalid": "格式错误",
  11. "min_length": "用户名最短8位"
  12. }
  13. )
  14. pwd = forms.CharField(min_length=6, label="密码")
  15. gender = forms.fields.ChoiceField(
  16. choices=((1, "男"), (2, "女"), (3, "保密")),
  17. label="性别",
  18. initial=3,
  19. widget=forms.widgets.RadioSelect()
  20. )
  21. 单选Select
  22. class LoginForm(forms.Form):
  23. ...
  24. hobby = forms.ChoiceField(
  25. choices=((1, "篮球"), (2, "足球"), (3, "双色球"), ),
  26. label="爱好",
  27. initial=3,
  28. widget=forms.widgets.Select()
  29. )
  30. 多选Select
  31. class LoginForm(forms.Form):
  32. ...
  33. hobby = forms.MultipleChoiceField(
  34. choices=((1, "篮球"), (2, "足球"), (3, "双色球"), ),
  35. label="爱好",
  36. initial=[1, 3],
  37. widget=forms.widgets.SelectMultiple()
  38. )
  39. 单选checkbox
  40. class LoginForm(forms.Form):
  41. ...
  42. keep = forms.ChoiceField(
  43. label="是否记住密码",
  44. initial="checked",
  45. widget=forms.widgets.CheckboxInput()
  46. )
  47. 多选checkbox
  48. class LoginForm(forms.Form):
  49. ...
  50. hobby = forms.MultipleChoiceField(
  51. choices=((1, "篮球"), (2, "足球"), (3, "双色球"),),
  52. label="爱好",
  53. initial=[1, 3],
  54. widget=forms.widgets.CheckboxSelectMultiple()
  55. )

Cookie与Session组件

cookie是保存在客户端浏览器上的信息
session是保存在服务端上的信息
session是基于cookie工作的

cookie操作

  1. # 校验登陆是否登陆装饰器
  2. def login_auth(func):
  3. def inner(request, *args, **kwargs):
  4. #获取url(路由+?后数据)
  5. target_url = request.get_full_path()
  6. #获取cookie
  7. if request.COOKIES.get('username'):
  8. res = func(request, *args, **kwargs)
  9. return res
  10. else:
  11. #将上一次访问的页面URL传值给login
  12. return redirect('/login/?next=%s' % target_url)
  13. return inner
  14. def login(request):
  15. if request.method == 'POST':
  16. username = request.POST.get('username')
  17. password = request.POST.get('password')
  18. if username == 'wyy' and password == '123':
  19. target_url = request.GET.get('next')
  20. if target_url:
  21. obj = redirect(target_url)
  22. else:
  23. obj = redirect('/home/')
  24. #设置cookie.时长10分钟,针对IE浏览器需要用expires参数设置时长
  25. obj.set_cookie('username', 'wyy',max_age=600,)
  26. obj.set_cookie('username', 'wyy',expires=600,)
  27. return obj
  28. return render(request, 'login.html')
  29. @login_auth
  30. def home(request):
  31. return HttpResponse('home页面')
  32. @login_auth
  33. def index(request):
  34. return HttpResponse('index页面')
  35. @login_auth
  36. def test(request):
  37. return HttpResponse('test页面')
  38. #注销功能
  39. @login_auth
  40. def logout(request):
  41. obj = redirect('/login/')
  42. obj.delete_cookie('username')
  43. return obj

session操作

默认情况下,需要django_session表,django默认过期时间14天
同一计算机同一浏览器在django_session中一条数据,不同浏览器不同数据,为了节省服务端资源
django_session过期的数据会自动清除

  1. #设置session
  2. def set_session(request):
  3. request.session['hobby'] = 'girl'
  4. request.session.set_expiry() #参数:整数--秒 日期对象--指定日期过期 0--当前浏览器则失效 不写-- django默认失效时间
  5. return HttpResponse('session')
  6. """
  7. 1.自动生成随机字符串
  8. 2.自动存储到django_session中
  9. 3.将随机字符串返回给浏览器
  10. """
  11. #获取session
  12. def get_session(request):
  13. request.session.get('hobby')
  14. """
  15. 1.自动获取sessionid对应的随机字符串
  16. 2.自动前往django_session中匹配
  17. 3. 匹配上了则以字典的形式封装到request.session中
  18. 没有则返回NONE
  19. """
  20. #清除session
  21. def del_session(request):
  22. request.session.delete() #删除服务端session
  23. request.session.flush() #删除客户端与服务端session

session登陆验证

  1. from functools import wraps
  2. def check_login(func):
  3. @wraps(func)
  4. def inner(request, *args, **kwargs):
  5. next_url = request.get_full_path()
  6. if request.session.get("user"):
  7. return func(request, *args, **kwargs)
  8. else:
  9. return redirect("/login/?next={}".format(next_url))
  10. return inner
  11. def login(request):
  12. if request.method == "POST":
  13. user = request.POST.get("user")
  14. pwd = request.POST.get("pwd")
  15. if user == "alex" and pwd == "alex1234":
  16. # 设置session
  17. request.session["user"] = user
  18. # 获取跳到登陆页面之前的URL
  19. next_url = request.GET.get("next")
  20. # 如果有,就跳转回登陆之前的URL
  21. if next_url:
  22. return redirect(next_url)
  23. # 否则默认跳转到index页面
  24. else:
  25. return redirect("/index/")
  26. return render(request, "login.html")
  27. @check_login
  28. def logout(request):
  29. # 删除所有当前请求相关的session
  30. request.session.delete()
  31. return redirect("/login/")
  32. @check_login
  33. def index(request):
  34. current_user = request.session.get("user", None)
  35. return render(request, "index.html", {"user": current_user})

CBV内方法加装饰器

  1. # CBV内方法加装饰器
  2. from django.views import View
  3. from django.utils.decorators import method_decorator
  4. # @method_decorator(login_auth,name='get') 方式二,可以叠加多个
  5. class Mylogin(View):
  6. # @method_decorator(login_auth) 方式三,直接作用于类内所有方法
  7. # def dispatch(self, request, *args, **kwargs):
  8. # pass
  9. # @method_decorator(login_auth) 方式一
  10. def get(self):
  11. return HttpResponse('get请求')
  12. def post(self):
  13. return HttpResponse('post请求')