zoukankan      html  css  js  c++  java
  • Django forms组件

    一、forms组件使用  

      form django import forms

      1  自定义一个类,类需要继承forms.Form 

          自定义类的字段   映射   模板(html)中的form表单中的各种标签

      2. 模板利用 RegForm类的实例对象 form_obj进行渲染:

          自定义类RegForm的属性 CharField字段    映射   form表单的input标签

          

          

          

     

          1. form_obj.as_p --> 简单演示
          2.  form_obj.username         --> input标签
            form_obj.username.label      --> label名称(即label标签)
            form_obj.username.id_for_label  --> label标签for属性使用的id
            form_obj.errors          --> 用ul标签把所有的错误展示出来
            form_obj.username.errors.0     --> 取具体某个input标签(即RegForm属性字段)的第一个错误提示信息


      3. 视图views.py:
          1. 实例化
          form_obj = RegForm(request.POST)
          2. 数据有效性校验
            form_obj.is_valid()
              - true 表示数据没有问题
              - form_obj.cleaned_data --> 保存经过校验的数据的大字典

        类示例:

    from django import forms
    from django.core.validators import RegexValidator
    from formapp import models
    
    
    class RegForm(forms.Form):
        username = forms.CharField(
            min_length=2, max_length=8, label='用户名',
            error_messages={'min_length': '用户名不得少于2位', 'max_length': '用户名不得超过8位',
                            'required': '用户名不能为空'},
            widget=forms.widgets.TextInput(
                attrs={'class': 'form-control', 'placeholder': '请输入用户名'}
            )
        )
    
        password = forms.CharField(
            label='密码', error_messages={'required': '密码不能为空'},
            widget=forms.widgets.PasswordInput(
                attrs={'class': 'form-control', 'placeholder': '请输入密码'},
                render_value=True
            )
        )
    
        re_pwd = forms.CharField(
            label='确认密码', error_messages={'required': '确认密码不能为空'},
            widget=forms.widgets.PasswordInput(
                attrs={'class': 'form-control', 'placeholder': '请重复密码'},
                render_value=True
    
            )
        )
    
        phone = forms.CharField(
            label='手机号', error_messages={'required': '手机号不能为空'},
            validators=[RegexValidator(r'1[3-9]d{9}$'), ],
            widget=forms.widgets.TextInput(
                attrs={'class': 'form-control', 'placeholder': '请输入手机号'},
            )
        )
    
        gender = forms.ChoiceField(
            label='性别',
            choices=((1, ''), (2, ''), (3, '保密')),
            initial=3,
            widget=forms.widgets.RadioSelect(
                attrs={'class': 'list-inline'}
            )
        )
        hobby = forms.MultipleChoiceField(
            label='爱好',
            widget=forms.widgets.CheckboxSelectMultiple(
                attrs={'class': 'list-inline'}
            )
        )
    
        """
        forms组件ChoiceField字段的choices若写成动态的从数据库中取数据,由于是静态字段,那么forms会为了
        保证页面的加载速度,会把第一次取来的数据放进缓存里边,所以若此时数据库数据有改动,页面并不会随
        着动态的改动。我们可以有两种方式解决这个问题。
        """
    
        # 总结:静态字段,获取的值无法实时更新
    
        # 重写父类__init__()
        def __init__(self, *args, **kwargs):
            super(RegForm, self).__init__(*args, **kwargs)
            self.fields['hobby'].choices = models.Hobby.objects.all().values_list('id', 'name')
    
        # 把forms字段跟models绑定
        # from django.forms import models as form_model
        # 
        # hobby = form_model.ModelMultipleChoiceField(
        #     queryset=models.Hobby.objects.all().values_list(),
        #     label='爱好',
        #     widget=forms.widgets.CheckboxSelectMultiple(
        #         attrs={'class': 'list-inline'}
        #     )
        # )
    forms.py各种示例
     1 <!DOCTYPE html>
     2 <html lang="en">
     3 <head>
     4     <meta charset="UTF-8">
     5     <title>注册</title>
     6     <link rel="stylesheet" href="/static/css/bootstrap/bootstrap3.3.7-min.css">
     7 </head>
     8 <body>
     9 <div class="container col-md-4 col-md-push-3" style="margin-top: 80px">
    10 
    11     <form class="form-horizontal" action="{% url 'reg' %}" novalidate method="post">
    12         {% csrf_token %}
    13         <div class="form-group">
    14             <label class="col-sm-3 control-label"
    15                    for="{{ form_obj.username.id_for_label }}">{{ form_obj.username.label }}</label>
    16             <div class="col-sm-9">
    17                 {{ form_obj.username }}
    18                 {{ form_obj.username.errors.0 }}
    19             </div>
    20         </div>
    21         <div class="form-group">
    22             <label class="col-sm-3 control-label"
    23                    for="{{ form_obj.password.id_for_label }}">{{ form_obj.password.label }}</label>
    24             <div class="col-sm-9">
    25                 {{ form_obj.password }}
    26                 {{ form_obj.password.errors.0 }}
    27             </div>
    28         </div>
    29         <div class="form-group">
    30             <label class="col-sm-3 control-label"
    31                    for="{{ form_obj.re_pwd.id_for_label }}">{{ form_obj.re_pwd.label }}</label>
    32             <div class="col-sm-9">
    33                 {{ form_obj.re_pwd }}
    34                 {{ form_obj.re_pwd.errors.0 }}
    35             </div>
    36         </div>
    37         <div class="form-group">
    38             <label class="col-sm-3 control-label"
    39                    for="{{ form_obj.phone.id_for_label }}">{{ form_obj.phone.label }}</label>
    40             <div class="col-sm-9">
    41                 {{ form_obj.phone }}
    42                 {{ form_obj.phone.errors.0 }}
    43             </div>
    44         </div>
    45         <div class="form-group">
    46             <label class="col-sm-3 control-label">{{ form_obj.gender.label }}</label>
    47             <div class="col-sm-9" style="margin-top: 5px">
    48                 {{ form_obj.gender }}
    49             </div>
    50         </div>
    51         <div class="form-group">
    52             <label class="col-sm-3 control-label">{{ form_obj.hobby.label }}</label>
    53             <div class="col-sm-9" style="margin-top: 6px">
    54                 {{ form_obj.hobby }}
    55             </div>
    56         </div>
    57         <div class="form-group">
    58             <div class="col-sm-push-4 col-sm-7">
    59                 <button type="submit" class="btn btn-block btn-lg btn-success">注册</button>
    60             </div>
    61         </div>
    62     </form>
    63 
    64 </div>
    65 </body>
    66 </html>
    reg.html模板渲染
     1 from django.shortcuts import render, HttpResponse
     2 from formapp.forms import RegForm
     3 # Create your views here.
     4 
     5 
     6 def reg(request):
     7     form_obj = RegForm()
     8     if request.method == 'POST':
     9         form_obj = RegForm(request.POST)
    10         if form_obj.is_valid():
    11             return HttpResponse('注册成功')
    12     return render(request, 'reg.html', {'form_obj': form_obj})
    views.py视图

      forms组件ChoiceField字段的choices若写成动态的从数据库中取数据,那么forms会为了保证页面的加载速度,
      会把第一次取来的数据放进缓存里边,所以若此时数据库数据有改动,页面并不会随着动态的改动。我们可以
      有两种方式解决这个问题。

      参考:https://www.cnblogs.com/liwenzhou/p/9030211.html

      方式一: 重写父类__init__()   

        def __init__(self, *args, **kwargs):
            super(RegForm, self).__init__(*args, **kwargs)
            self.fields['hobby'].choices = models.Hobby.objects.all().values_list('id', 'name')
    在RegFom类中重写父类__init__()

      方式二:绑定models

        # 把forms字段跟models绑定
        from django.forms import models as form_model
    
        hobby = form_model.ModelMultipleChoiceField(
            queryset=models.Hobby.objects.all().values_list(),
            label='爱好',
            widget=forms.widgets.CheckboxSelectMultiple(
                attrs={'class': 'list-inline'}
            )
        )
    forms绑定models

    二、forms 的各种校验方法

      一、校验器

        1.django内置正则校验

            from django.core.validators import RegexValidator

           validators=[RegexValidator(r'1[3-9]d{9}$'), ],

        2.自定义方法

          def name_check(value):

            if '哒哒哒' in value:

              raise ValidationError("不符合社会主义核心价值观!")
            else:
              return value

          使用:

          validators=[ name_check,]

      二、局部钩子:clean_字段名() 方法

         def  clean_name(self):

            print("我看了源码,你应该会帮我执行这个方法!")
            value = self.cleaned_data.get("name")
            if "哒哒哒" in value:
               raise ValidationError("不符合社会主义核心价值观!")
            else:
               return value

         def clean_name(self):
              print("我看了源码,你应该会帮我执行这个方法!")
              value = self.cleaned_data.get("name")
              if "哒哒哒" in value:
                  raise ValidationError("不符合社会主义核心价值观!")
              else:
                  return value

          

      三、全局钩子:重写clean()方法

        校验两次密码是否一致

          def clean(self):
              print("我可是看过源码的人,我知道你肯定会执行这个方法!")
              # 重写父类的clean方法
              # 该clean方法, 在每个字段都校验通过之后才调用执行
              pwd = self.cleaned_data.get("pwd")
              re_pwd = self.cleaned_data.get("re_pwd")
    
              if re_pwd and re_pwd == pwd:
                  # 确认密码和密码相同, 正常
                  return self.cleaned_data
              else:
                  # 确认密码和密码不同
                  self.add_error('re_pwd', "两次密码不一致")
                  raise ValidationError("两次密码不一致")

    形参

    *  收集(单参数)(位置参数)

    ** 收集(键值对)(关键字参数)

    实参

    * 按(单值)打散

    **按(键值对)打散

    ok

  • 相关阅读:
    如何找出阻塞的线程正在等待哪个线程
    探索Windows 10的CFG机制
    异常0xc000041d的抛出过程
    异常STATUS_FATAL_USER_CALLBACK_EXCEPTION(0xc000041d)
    VisualStudio中集成扩展调试SOS
    clr调试扩展和DAC
    WinDbg常用命令系列---sx, sxd, sxe, sxi, sxn, sxr, sx- (设置异常)
    CLR调试时的sos.dll/clr.dll/mscorwks.dll/mscordacwks.dll等动态库的版本对应
    WinDbg常用命令系列---!runaway
    WinDbg常用命令系列---!findstack
  • 原文地址:https://www.cnblogs.com/kingon/p/9448386.html
Copyright © 2011-2022 走看看