• Django-Form组件-forms.ModelForm


    froms.ModelForm

    具有models操作数据库字段的功能,还具有Form的功能。较Form组件而言,根据model自动生成Form。

    使用注册的案例进行初步认识

    # 使用ModelForm创建Form模板
    
    from django import forms
    class RegForm(forms.ModelForm):
        re_password = forms.CharField(min_length=6,
                                      widget=forms.PasswordInput(attrs={'placeholder': '确认密码', 'autocomplete': 'off'}),
                                      label='确认密码', )
    
        class Meta:
            model = models.UserProfile
            fields = '__all__'
            ecclude = ['is_active', 'memo']
    
            min_lengths = {'password': 6}
            
    		# 定义字段的widgets属性
            widgets = {
                'username': forms.EmailInput(attrs={'placeholder': '用户名', 'autocomplete': 'off'}),
                'password': forms.PasswordInput(attrs={'placeholder': '密码', 'autocomplete': 'off'}),
                'name': forms.TextInput(attrs={'placeholder': '姓名', 'autocomplete': 'off'}),
                'mobile': forms.TextInput(attrs={'placeholder': '手机号', 'autocomplete': 'off'}),
            }
    		
    		# 定义每一个字段的labels属性
            labels = {
                'username': '用户名',
                'password': '密码',
                'name': '姓名',
                'mobile': '手机号',
                'department': '部门'
            }
    	# 可以使用局部钩子
        def clean_mobile(self):
            phone = self.cleaned_data.get('mobile')
            ret = re.match(r"^1[35678]d{9}$", phone)
            if ret:
                return phone
            else:
                raise ValidationError('手机格式不正确')
    
        def clean_username(self):
            user = self.cleaned_data.get('username')
            obj = models.UserProfile.objects.get(username=user)
            if obj:
                raise ValidationError('该用户已存在')
            return user
            
    	# 可以定义全局钩子
        def clean(self):
            self._validate_unique = True  # 去数据库检验唯一性
            password = self.cleaned_data.get('password')
            re_password = self.cleaned_data.get('re_password')
            if password == re_password:
                md5 = hashlib.md5()
                md5.update(password.encode('utf-8'))
                self.cleaned_data['password'] = md5.hexdigest()
                return self.cleaned_data
            self.add_error('re_password', '两次密码不一致')  # 将全局的错误信息添加到字段错误列表中
            raise ValidationError('两次密码不一致')
    

    在views视图函数中进行实例化

    def reg(request):
        form_obj = RegForm()
        if request.method == 'POST':
            form_obj = RegForm(request.POST)
            if form_obj.is_valid():   
                form_obj.save()
                return redirect('app01:login')
        return render(request, 'logon.html', {'form_obj': form_obj})
    

    在htm中进行展示

    <form action="" method="post">
        {% csrf_token %}
        <div>{# 注册账户 #}
            {{ form_obj.username }}  {{ form_obj.username.errors.0 }}
        </div>
        <div>{# 注册密码 #}
            {{ form_obj.password }}  {{ form_obj.password.errors.0 }}
        </div>
        <div>{# 密码确认 #}
            {{ form_obj.re_password }}  {{ form_obj.re_password.errors.0 }}
        </div>
        <div>{# 真实姓名 #}
            {{ form_obj.name }}  {{ form_obj.name.errors.0 }}
        </div>
        <div>{# 注册部门 #}
            {{ form_obj.department }}  {{ form_obj.department.errors.0 }}
        </div>
        <div>{# 注册手机号 #}
            {{ form_obj.mobile }}  {{ form_obj.mobile.errors.0 }}
        </div>
        <div>
            {{ error }}
        </div>
        <button id="submit">Sign on</button>
    </form>
    

    知识点-class Meta

    class Meta是一个内部类,作用是定义Form模型的特殊性质

    class Meta中常用的参数有:

    model = models.UserProfile  # 根据一个具体的model表进行form的创建
    fields = "__all__"  # 字段,如果是__all__,就是表示列出所有的字段
    exclude = None  # 排除的字段
    labels = None  # 提示信息
    help_texts = None  # 帮助提示信息
    widgets = None  # 自定义插件
    error_messages = None  # 自定义错误信息
    field_classes=None   # 自定义字段类 (也可以自定义字段)
    

    知识点-验证和其他

    # views中进行写入验证
    form_obj.is_valid()  # 数据库保存数据之前,判断该条记录能否写入
    
    # vies中进行保存
    form_obj.save()
    
    # 可以重写全局钩子和局部钩子
    
    # 全局钩子中
    self._validate_unique = True  # 去数据库检验进行unique判断,不设置时会有唯一性异常
    

    数据添加和修改中的应用

    路由

    url(r'^customer_add/', views.customer_operate,name='customer_add'),
    url(r'^customer_edit/(d+)/', views.customer_operate,name='customer_edit'),
    

    视图函数

    def customer_operate(request, pk=None):
        obj = models.Customer.objects.filter(pk=pk).first()
        form_obj = OperateForm(instance=obj)
        if request.method == 'POST':
            form_obj = OperateForm(request.POST, instance=obj)
            if form_obj.is_valid():
                form_obj.save()  # save
                next = request.GET.get('next')
                if next:
                    return redirect(next)
                return redirect('app01:mine_customer')
        title = '编辑客户信息' if pk else '添加用户信息'
        return render(request, 'customeroperate.html', {'form_obj': form_obj, 'title': title})
    
    

    ModelForm

    class BaseForm(forms.ModelForm):
        def __init__(self, *args, **kwargs):
            super().__init__(*args, **kwargs)
            # 自定义操作,循环添加class操作,当遇到MultiSelectFormField或者forms.BooleanField框时,不加class类
            for name, field in self.fields.items():
                # if name == 'course'  # 可以直接判断字段名
                if isinstance(field, (MultiSelectFormField, forms.BooleanField)):
                    # 判断字段类型是MultiSelectFormField, forms.BooleanField还可以根据需求继续添加到元组中,让他们的格式不接受form-control的样式
                    continue
                # 方式一:
                field.widget.attrs['class'] = 'form-control'
                # 方式二:
                # field.widget.attrs.update({'class': 'form-control'})
    
    
    # 新增和编辑客户form组件
    class OperateForm(BaseForm):
    
        class Meta:
            model = models.Customer
            fields = '__all__'
    

    html中

    <form class="form-horizontal" action="" method="post" novalidate >
          {% csrf_token %}
          {% for customer in form_obj %}
    
         <div class="form-group {% if customer.errors %} has-error {% endif %}">
               <label for="{{customer.id_for_label}}"
                               class="col-sm-3 control-label {% if not customer.field.required %} not_required {% endif %}">
                                {{customer.label}}</label>
              <div class="col-sm-4">
                            {{ customer }}
                        </div>
                        <p class="col-sm-4"><span>{{ customer.errors.0 }}</span></p>
    
               </div>
                    {% endfor %
    
               <div class="form-group">
                        <div class="col-sm-offset-2 col-sm-10">
                            <button type="submit" class="btn btn-primary">保存</button>
                        </div>
                    </div>
                </form>
    
  • 相关阅读:
    jvm系列(二):JVM内存结构
    jvm系列(一):java类的加载机制
    配置中心选型
    抓取某一个网站整站的记录
    jvm系列(五):tomcat性能调优和性能监控(visualvm)
    网站文件系统发展&&分布式文件系统fastDFS
    spring aop
    禁止页面后退JS(兼容各浏览器)
    spring ioc
    spring帝国-开篇
  • 原文地址:https://www.cnblogs.com/jjzz1234/p/11629874.html
Copyright © 2020-2023  润新知