• Django之ModelForm使用


    一:什么是ModelForm呢?

    Model + Form ==> ModelForm。model和form的结合体,所以有以下功能:

    • 数据验证
    • 数据库操作

    model有操作数据库的字段,form验证也有那几个字段,虽然耦合度降低,但是代码是有重复的。如果利用model里的字段,那是不是form里的字段就不用写了。

    二:下面是一个简单是例子:
    from django.db import models
    
    class CustomerInfo(models.Model):
        """客户表"""
        name = models.CharField(max_length=64)
        contact_type_choices = ((0,'QQ'),(1,'微信'),(2,'手机'))
        contact_type = models.SmallIntegerField(choices=contact_type_choices)
        contact = models.CharField(max_length=64,unique=True,verbose_name="联系方式")
        source_choices = ((0,'QQ群'),(1,'51CTO'),(2,'百度推广'),(3,'知乎'),(4,'转介绍'),(5,'其它'))
        source = models.SmallIntegerField(choices=source_choices,verbose_name="客户来源")
        referral_from = models.ForeignKey("self",blank=True,null=True,verbose_name="转介绍",on_delete=models.CASCADE)
        consult_courses = models.ManyToManyField("Course",verbose_name="咨询课程")
        consult_content = models.TextField(verbose_name="咨询内容")
        status_choices = ((0, '未报名'), (1, '已报名'), (2, '已退学'))
        status = models.SmallIntegerField(choices=status_choices,verbose_name="状态")
        consultant = models.ForeignKey("UserProfile",verbose_name="课程顾问",on_delete=models.CASCADE)
        date = models.DateField(auto_now_add=True)
        def __str__(self):
            return self.name
    models.py
    from django.forms import ModelForm
    from crm import models
    from django import forms
    
    class CustomerForm(ModelForm):
        class Meta:
            model = models.CustomerInfo
            fields = '__all__'
            exclude = ['consult_content', 'status', 'consult_courses']
            readonly_fields = ['contact_type','contact','consultant','referral_from','source']   #并不是真正的设置可读模式,而是用于自定制
    
        def __new__(cls, *args, **kwargs):      # cls 就是实例(self)
            for field_name in cls.base_fields:
                field_obj = cls.base_fields[field_name]
                field_obj.widget.attrs.update({'class':'form-control'})
                if field_name in cls.Meta.readonly_fields:
                    field_obj.widget.attrs.update({'disabled':'true'})
                    # print(cls.Meta)
            # print(cls.Meta.exclude)
            return ModelForm.__new__(cls)
    
        def clean(self):
            """对数据进行验证,此方法需要在form.is_valid()后才能生效"""
            # print("cleaned_dtat:", self.cleaned_data)
            if self.errors:  # 表单级别的错误
                raise forms.ValidationError(("Please fix errors before re-submit."))
            for field in self.Meta.readonly_fields:
                old_field_val = getattr(self.instance,field)
                new_form_val = self.cleaned_data[field]
                if old_field_val != new_form_val:
                    self.add_error(field,"Readonly Field: field should be '{value}' ,not '{new_value}' ".
                                             format(**{'value':old_field_val,'new_value':new_form_val}))
    forms
    def enrollment(request,enrollment_id):
        """②学员确认信息"""
        customer_form = forms.CustomerForm(instance=enrollment_obj.customer)
        
        if request.method == "POST":
            customer_form = forms.CustomerForm(instance=enrollment_obj.customer,data=request.POST)
            if customer_form.is_valid():
                customer_form.save()
                return HttpResponse('合同正在审核中,请等候...')
    
        return render(request,'crm/enrollment.html',locals())
    views

    注意我们如何在POST和GET情况下传递实例(instance)。

    三、Meta的作用:

    • ModelForm 通过 Meta 把 db.Field 自动转化为 forms.Field,其中涉及到几步转化
    • validators 不变
    • 添加 widget 属性,即前端的渲染方式
    • 修改 Model 包含的字段,通过 fields 来拿指定字段或者通过 exclude 来排除指定字段
    • 修改错误信息
    class Meta:
            model = models.UserInfo
            fields = '__all__'
            # fields =  ['username','email']
            # exclude = ['username']
            labels = {
                'username': '用户名',
                'email': '邮箱',
            }
            help_texts = {
                'username': '...'
            }
            widgets = {
                'username': Fwidgets.Textarea(attrs={'class': 'c1'})
            }
            error_messages = {
                '__all__':{
     
                },
                'email': {
                    'required': '邮箱不能为空',
                    'invalid': '邮箱格式错误..',
                }
            }
            field_classes = {
                # 'email': Ffields.URLField
            }
     
            # localized_fields=('ctime',)
    Meta的另一个例子
  • 相关阅读:
    jquery 实现 html5 placeholder 兼容password密码框
    php返回json的结果
    使用PHP读取远程文件
    Sharepoint 自定义字段
    Sharepoint 中新增 aspx页面,并在页面中新增web part
    【转】Sharepoint 2010 配置我的站点及BLOG
    JS 实现 Div 向上浮动
    UserProfile同步配置
    【转】Import User Profile Photos from Active Directory into SharePoint 2010
    Sharepoint 2010 SP1升级后 FIMSynchronizationService 服务无法开启
  • 原文地址:https://www.cnblogs.com/ray-h/p/10415269.html
Copyright © 2020-2023  润新知