Django Form ModelForm modelfromset

Django forms 组件

Form

  1. form表单完成的事情

    1. 提供input可以提交数据
    2. 对提交的数据进行校验
    3. 提供错误提示
  2. 定义form组件

    from django import forms
    
    class RegForm(forms.Form):
        user = forms.CharField(label='用户名')   # input 输入框 
        pwd = forms.CharField(label='密码')    #  label 提示  <label> 标签值
    
  3. 使用 form 组件
    视图中:

    form_obj = RegForm()   # 实例化form对象
    return render(request, 'reg2.html', {'form_obj': form_obj})
    

    模板中:
    form 标签加上 novalidate 前端不进行校验

    {{ form_obj.as_p }}   ——》  生成所有的p标签   label  input
    {{ form_obj.errors }}   ——》所有字段的错误
    {{ form_obj.user }}   ——》 该字段的input框
    {{ form_obj.user.label }}   ——》 该字段的label  中文提示
    {{ form_obj.user.id_for_label }}   ——》 该字段的id
    {{ form_obj.user.errors }}   ——》 该字段的所有的错误信息
    {{ form_obj.user.errors.0 }} ——》 该字段的第一个的错误信息
    {{ form_obj.get_字段名_display }}   ——》 该字段含有  chices 的 值
    

    字段:

    forms.CharField(label='用户名')     # input 输入框 
    forms.ChoiceField(label='用户名')   # select框 单选
    forms.MultipleChoiceField(label='用户名')     #  多选框
    forms.EmailField(label='用户名')     # Email 输入框   自动校验 email 格式
    

    字段的参数:

    required=True,               是否允许为空
    widget=None,                 HTML插件
    
    min_length=8  				最小长度
    max_length=16  				最大长度
    
    label=None,                  用于生成Label标签或显示内容
    
    initial=None,                初始值    
    
    error_messages=None,         错误信息 {'required': '不能为空', 'invalid': '格式错												误','min_length':'用户名位数不足'}
    validators=[],               自定义验证规则  func函数 ==
    
    disabled=False,              是否可以编辑
    
    choices=((1,'男'),(2,'女'),(3,'未知'),)   多选框 或单选框的 选项
    
    widgte=forms.passwordInput()  		改为密码输入框 
    widgte=forms.SelectMultiple  		改为多选框
    widgte=forms.RadioSelect()  		改为单选列表
    widgte=forms.ChectboxSelectMutiple   改为密码输入框 
    

    校验:

    1. 内置校验
      required=True,min_length=8,max_length=12, ........
    2. 自定义的校验(自定义校验器)
      • 定义函数

        from django.core.exceptions import ValidationError
        def check(value):
            if '苍老师' in value:
                raise ValidationError('敏感词汇,不符合社会职业核心价值观')
        
        # 使用 添加到 自定义验证规则的  参数中        
        validators=[check]
        
      • 正则 匹配 re

        from django.core.validators import RegexValidator
        # 手机号匹配规则
        validators=[RegexValidator(r'^1[3-9]\d{9}$', '格式不正确')]
        

    钩子校验: (Hook)
    1.局部钩子
    clean_字段名(self,)
    通过校验 返回通过校验的值
    不通过 抛出异常 ValidationError

    def clean_user(self):
        value = self.cleaned_data.get('user')
        if 'cangjingkong' in value:
            raise ValidationError('不符合社会职业核心价值观')
        return value
    

    2.全局钩子
    clean(self,)
    self.add_error(name,'错误提示')
    通过校验 返回通过校验self.cleaned_data
    不通过 抛出异常 ValidationError

    def clean(self):
        pwd = self.cleaned_data.get('pwd')
        re_pwd = self.cleaned_data.get('re_pwd')
    
        if pwd != re_pwd:
            self.add_error('re_pwd', '两次密码不一致!!@!')   # 添加错误信息
            raise ValidationError('两次密码不一致')   # 抛出异常
    
        return self.cleaned_data
    

    流程:
    form_obj = RegForm()
    form_obj = RegForm(request.POST)
    form_obj .save() 保存或 更改数据
    form_obj.is_valid() 是否通过校验
    form_obj.cleaned_data 经过校验的数据
    return render(request,'reg.html',{'form_obj ':form_obj })

    FBV 写法

    # 创建 和 修改  客户的方法  FBV
    def customer_edit(request, pk=None):
        ''' 创建 和 修改  客户的方法  '''
        # 通过分组 参数 的 id 获取 要修改的对象
        cus_obj = models.Customer.objects.filter(pk=pk).first()
        # 吧要修改 的对象通过 instance 传入form组件中
        form_obj = CustomerForm(instance=cus_obj)
        if request.method == 'POST':
            form_obj = CustomerForm(request.POST, instance=cus_obj)
            if form_obj.is_valid():
                # 如果 instance 有对象则是修改数据 没有就是 新增数据
                form_obj.save()
    
                return redirect(rev_url(request, 'show:public_customer'))
    
        return render(request, "form_edit.html", {'form_obj': form_obj, 'title': "修改用户" if cus_obj else '添加用户'})
    

    CBV 写法

    class Change_user(View):  CBV
    
        def get(self, request):
            '''显示用户信息 get 请求'''
            # 获取个人用户的对象
            user = UserProfileForm(instance=request.user_object)
    
            return render(request, 'form_edit.html', {'form_obj': user, 'title': '用户信息'})
    
        def post(self, request):
            ''' 修改个人数据 '''
            user = UserProfileForm(request.POST, instance=request.user_object)
            if user.is_valid():
                print(user.cleaned_data)
                user.save()    # 修改数据
                return self.get(request)  #  调用自己的 get 方法 展示页面
            return redirect(reverse('show:change_user'))
    

ModelForm

from django import forms
from django.core.exceptions import ValidationError
from django.core.validators import RegexValidator
from crm import models
import hashlib

class BootstrapForm(forms.ModelForm):
    # 重写__init__方法  
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        for field in self.fields.values():
            # 给所有的字段 添加 更新 属性  class="form-control"
            # print(field)
            field.widget.attrs.update({"class": "form-control", })
        # 给单个 标签 设置 属性
        self.fields['course'].widget.attrs.update({"class": "", })
            
    # 自定义的 input 框 创建 确认密码的字段
    password = forms.CharField(label='密码', widget=forms.PasswordInput(), min_length=6, )
    # attrs = {'placeholder': '数字 字母 下划线 下划线组成 最少6位'}
    re_password = forms.CharField(label='确认密码', widget=forms.PasswordInput(), min_length=6, )        
    
    class Meta:
        model = models.UserProfile   # 要 修改的model
        fields = "__all__"  	# 显示所有字段
        # fields = ['username', 'password']  显示 指定字段
        exclude = ['is_active']  # 不显示的 字段 不包含
        # 所有的显示 中文 提示  作用不到 自己添加的字段
        labels = {
            'username': '用户名emil',
            'password': '密码',
            'department': '部门'
        }
        # 所有的 widgets 参数
        widgets = {
            'password': forms.PasswordInput(),
        }
        # 所有的错误信息
        error_messages = {
            'username': {
                'required': "不能为空",
                'invalid': "格式不正确"
            },
            'name': {
                'required': "不能为空",
                'invalid': "格式不正确"
            }
        }

modelForm 中 获取 关联的所有对象 一对多

不同字段的显示

  1. 普通字段

  2. 含有choices字段
    {{ customer.get_sex_display }} # get_字段名_display() 方法 模板中不加()

  3. 其他字段
    多对多、特殊显示,在model中定义方法。

    def show_classes(self):
        return ' | '.join([str(i) for i in self.class_list.all()])
        
    def show_status(self):
        color_dict = {
            'signed': 'green',
            'unregistered': 'red',
            'studying': 'blue',
            'paid_in_full': 'yellow',
        }
    
        return '<span style="background-color: {};color: white;padding: 3px">{}</span>'.format(
            color_dict.get(self.status),
            self.get_status_display())
    

modelfromset 可修改的 form 在视图中使用

from django.forms import modelformset_factory

form_set_obj = modelformset_factory(models.StudyRecord, StudyRecordForm, extra=0)

    study_record_list = models.StudyRecord.objects.filter(pk=id)

    form_obj = form_set_obj(queryset=study_record_list)
    
    if request.method == 'POST':
        form_obj = form_set_obj(request.POST, queryset=study_record_list)
        if form_obj.is_valid():
            form_obj.save()
 
            return redirect(-----)

    return render(request, '------.html', {'form_obj': form_obj})

模板中使用

{{ form.instance }}   模板中使用原始的 form表单内容

注意 不然报错

form 表单中 要有  {{ form_obj.management_form }}
每一行中要有  {{ form.id }}
posted @ 2018-12-27 22:05  拐弯  阅读(320)  评论(0编辑  收藏  举报