将super与django ModelForm类结合使用以更改__init__方法

如何解决将super与django ModelForm类结合使用以更改__init__方法

在尝试一些代码想法时,我偶然发现了一个似乎无法解决的问题。

请忽略事实,为什么我要尝试这样做,问题只在于为什么它不起作用;)

因此,我想创建一个表单类,在其中重写基类的__init__方法,而只想复制它。

基本上我想做的是以下事情:

class A():
    def __init(self,a,b,c)__:
        self.a = a
        self.b = b
        self.c = c

class B(A):
    def __init__(self,c):
        super(B,self).__init__( a,c)
        
        # Do some stuff that was not implemented#

我希望B的__init__方法能够像没有任何变化一样正常工作,最后补充说明。但是在我的示例中,由于我的表单之后不再起作用,因此发生了一些确定的变化:

class SignUpForm_test(forms.ModelForm):

    password_confirmed  = forms.CharField(widget=forms.PasswordInput())

    # --> This is the important stuff,the rest is just for completeness <--#
    #########################################################################
    def __init__(self,data=None,files=None,auto_id='id_%s',prefix=None,initial=None,error_class=ErrorList,label_suffix=None,empty_permitted=False,instance=None,use_required_attribute=None,renderer=None):
        super().__init__( data=None,renderer=None)
    #########################################################################

    class Meta:
        model = get_user_model()
        fields = (  
                    "username","email","password"             
                )           
    
    def clean_password_confirmed(self):
        password             = self.cleaned_data.get('password')
        password_confirmed   = self.cleaned_data.get('password_confirmed')


        if password and password_confirmed:
            if password != password_confirmed:
                raise ValidationError(
                    message ='Passwörter müssen übereinstimmen',code    ='password_mismatch',)
        # password_validation.validate_password(password_confirmed)        
        return password_confirmed

感谢您的帮助以了解这一点!

这里是ModelForm和相关的BaseModelForm的源代码,因此您不必查找它:

class BaseModelForm(BaseForm):
def __init__(self,renderer=None):
    opts = self._meta
    if opts.model is None:
        raise ValueError('ModelForm has no model class specified.')
    if instance is None:
        # if we didn't get an instance,instantiate a new one
        self.instance = opts.model()
        object_data = {}
    else:
        self.instance = instance
        object_data = model_to_dict(instance,opts.fields,opts.exclude)
    # if initial was provided,it should override the values from instance
    if initial is not None:
        object_data.update(initial)
    # self._validate_unique will be set to True by BaseModelForm.clean().
    # It is False by default so overriding self.clean() and failing to call
    # super will stop validate_unique from being called.
    self._validate_unique = False
    super().__init__(
        data,files,auto_id,prefix,object_data,error_class,label_suffix,empty_permitted,use_required_attribute=use_required_attribute,renderer=renderer,)
    for formfield in self.fields.values():
        apply_limit_choices_to_to_formfield(formfield)

def _get_validation_exclusions(self):
    """
    For backwards-compatibility,exclude several types of fields from model
    validation. See tickets #12507,#12521,#12553.
    """
    exclude = []
    # Build up a list of fields that should be excluded from model field
    # validation and unique checks.
    for f in self.instance._meta.fields:
        field = f.name
        # Exclude fields that aren't on the form. The developer may be
        # adding these values to the model after form validation.
        if field not in self.fields:
            exclude.append(f.name)

        # Don't perform model validation on fields that were defined
        # manually on the form and excluded via the ModelForm's Meta
        # class. See #12901.
        elif self._meta.fields and field not in self._meta.fields:
            exclude.append(f.name)
        elif self._meta.exclude and field in self._meta.exclude:
            exclude.append(f.name)

        # Exclude fields that failed form validation. There's no need for
        # the model fields to validate them as well.
        elif field in self._errors:
            exclude.append(f.name)

        # Exclude empty fields that are not required by the form,if the
        # underlying model field is required. This keeps the model field
        # from raising a required error. Note: don't exclude the field from
        # validation if the model field allows blanks. If it does,the blank
        # value may be included in a unique check,so cannot be excluded
        # from validation.
        else:
            form_field = self.fields[field]
            field_value = self.cleaned_data.get(field)
            if not f.blank and not form_field.required and field_value in form_field.empty_values:
                exclude.append(f.name)
    return exclude

def clean(self):
    self._validate_unique = True
    return self.cleaned_data

def _update_errors(self,errors):
    # Override any validation error messages defined at the model level
    # with those defined at the form level.
    opts = self._meta

    # Allow the model generated by construct_instance() to raise
    # ValidationError and have them handled in the same way as others.
    if hasattr(errors,'error_dict'):
        error_dict = errors.error_dict
    else:
        error_dict = {NON_FIELD_ERRORS: errors}

    for field,messages in error_dict.items():
        if (field == NON_FIELD_ERRORS and opts.error_messages and
                NON_FIELD_ERRORS in opts.error_messages):
            error_messages = opts.error_messages[NON_FIELD_ERRORS]
        elif field in self.fields:
            error_messages = self.fields[field].error_messages
        else:
            continue

        for message in messages:
            if (isinstance(message,ValidationError) and
                    message.code in error_messages):
                message.message = error_messages[message.code]

    self.add_error(None,errors)

def _post_clean(self):
    opts = self._meta

    exclude = self._get_validation_exclusions()

    # Foreign Keys being used to represent inline relationships
    # are excluded from basic field value validation. This is for two
    # reasons: firstly,the value may not be supplied (#12507; the
    # case of providing new values to the admin); secondly the
    # object being referred to may not yet fully exist (#12749).
    # However,these fields *must* be included in uniqueness checks,# so this can't be part of _get_validation_exclusions().
    for name,field in self.fields.items():
        if isinstance(field,InlineForeignKeyField):
            exclude.append(name)

    try:
        self.instance = construct_instance(self,self.instance,opts.exclude)
    except ValidationError as e:
        self._update_errors(e)

    try:
        self.instance.full_clean(exclude=exclude,validate_unique=False)
    except ValidationError as e:
        self._update_errors(e)

    # Validate uniqueness if needed.
    if self._validate_unique:
        self.validate_unique()

def validate_unique(self):
    """
    Call the instance's validate_unique() method and update the form's
    validation errors if any were raised.
    """
    exclude = self._get_validation_exclusions()
    try:
        self.instance.validate_unique(exclude=exclude)
    except ValidationError as e:
        self._update_errors(e)

def _save_m2m(self):
    """
    Save the many-to-many fields and generic relations for this form.
    """
    cleaned_data = self.cleaned_data
    exclude = self._meta.exclude
    fields = self._meta.fields
    opts = self.instance._meta
    # Note that for historical reasons we want to include also
    # private_fields here. (GenericRelation was previously a fake
    # m2m field).
    for f in chain(opts.many_to_many,opts.private_fields):
        if not hasattr(f,'save_form_data'):
            continue
        if fields and f.name not in fields:
            continue
        if exclude and f.name in exclude:
            continue
        if f.name in cleaned_data:
            f.save_form_data(self.instance,cleaned_data[f.name])

def save(self,commit=True):
    """
    Save this form's self.instance object if commit=True. Otherwise,add
    a save_m2m() method to the form which can be called after the instance
    is saved manually at a later time. Return the model instance.
    """
    if self.errors:
        raise ValueError(
            "The %s could not be %s because the data didn't validate." % (
                self.instance._meta.object_name,'created' if self.instance._state.adding else 'changed',)
        )
    if commit:
        # If committing,save the instance and the m2m data immediately.
        self.instance.save()
        self._save_m2m()
    else:
        # If not committing,add a method to the form to allow deferred
        # saving of m2m data.
        self.save_m2m = self._save_m2m
    return self.instance

save.alters_data = True


class ModelForm(BaseModelForm,metaclass=ModelFormMetaclass):
pass

解决方法

问题出在您的super通话中。无需复制传递给方法的变量,而是使用默认值覆盖它们。改用它

    super().__init__( data=data,files=files,auto_id=auto_id,prefix=prefix,initial=initial,error_class=error_class,label_suffix=label_suffix,empty_permitted=empty_permitted,instance=instance,use_required_attribute=use_required_attribute,renderer=renderer)

另一种选择是简单地捕获所有参数:

def __init__(self,*args,**kwargs):
    super().__init__(*args,**kwargs)

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 &lt;select id=&quot;xxx&quot;&gt; SELECT di.id, di.name, di.work_type, di.updated... &lt;where&gt; &lt;if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 &lt;property name=&quot;dynamic.classpath&quot; value=&quot;tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-