首页 > 解决方案 > __init__() 得到了一个意外的关键字参数 'max_length' django charfield

问题描述

我有一个自定义字符域,init函数告诉我 max_length 是意外的

class field(CharField):

    description = _("CharField")

    def __init__(self, *args, **kwargs):
        kwargs['max_length'] = 10
        super().__init__(*args, **kwargs)

    def formfield(self, **kwargs):
        defaults = {'form_class': fields.field}
        defaults.update(kwargs)
        return super().formfield(**defaults)

这是回溯:

Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/django/core/handlers/exception.py", line 47, in inner
    response = get_response(request)
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/django/core/handlers/base.py", line 181, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/django/contrib/admin/options.py", line 614, in wrapper
    return self.admin_site.admin_view(view)(*args, **kwargs)
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/django/utils/decorators.py", line 130, in _wrapped_view
    response = view_func(request, *args, **kwargs)
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/django/views/decorators/cache.py", line 44, in _wrapped_view_func
    response = view_func(request, *args, **kwargs)
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/django/contrib/admin/sites.py", line 233, in inner
    return view(request, *args, **kwargs)
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/django/contrib/admin/options.py", line 1653, in add_view
    return self.changeform_view(request, None, form_url, extra_context)
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/django/utils/decorators.py", line 43, in _wrapper
    return bound_method(*args, **kwargs)
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/django/utils/decorators.py", line 130, in _wrapped_view
    response = view_func(request, *args, **kwargs)
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/django/contrib/admin/options.py", line 1534, in changeform_view
    return self._changeform_view(request, object_id, form_url, extra_context)
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/django/contrib/admin/options.py", line 1567, in _changeform_view
    fieldsets = self.get_fieldsets(request, obj)
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/django/contrib/admin/options.py", line 335, in get_fieldsets
    return [(None, {'fields': self.get_fields(request, obj)})]
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/django/contrib/admin/options.py", line 326, in get_fields
    form = self._get_form_for_get_fields(request, obj)
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/django/contrib/admin/options.py", line 666, in _get_form_for_get_fields
    return self.get_form(request, obj, fields=None)
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/django/contrib/admin/options.py", line 709, in get_form
    return modelform_factory(self.model, **defaults)
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/django/forms/models.py", line 555, in modelform_factory
    return type(form)(class_name, (form,), form_class_attrs)
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/django/forms/models.py", line 253, in __new__
    fields = fields_for_model(
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/django/forms/models.py", line 179, in fields_for_model
    formfield = formfield_callback(f, **kwargs)
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/django/contrib/admin/options.py", line 182, in formfield_for_dbfield
    return db_field.formfield(**kwargs)
  File "/Users/computer/Desktop/hanohov/main/models.py", line 57, in formfield
    return super().formfield(**defaults)
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/django/db/models/fields/__init__.py", line 1042, in formfield
    return super().formfield(**defaults)
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/django/db/models/fields/__init__.py", line 929, in formfield
    return form_class(**defaults)

Exception Type: TypeError at /admin/main/account/add/
Exception Value: __init__() got an unexpected keyword argument 'max_length'

我不明白,django 说 charfield 必须有 max_length。

class field(Field):
    default_error_messages = {
        'invalid': _('Enter a valid ID number.'),
    }

    def clean(self, value):
        value = super().clean(value)
        id_number_re = re.compile(r'^(?P<number>\d{1,8})-?(?P<check>\d)$')
        if value in EMPTY_VALUES:
            return ''

        match = id_number_re.match(value)
        if not match:
            raise ValidationError(self.error_messages['invalid'], code='invalid')

        value = match.group('number') + match.group('check')
        if not luhn.is_valid(value):
            raise ValidationError(self.error_messages['invalid'], code='invalid')
        return value

标签: pythondjango

解决方案


您的自定义表单小部件fields.field类不接受默认添加的参数(当您调用时max_length)。models.CharField.formfieldsuper().formfield(**defaults)

要么你在__init__你的field类中添加一个接受(也许只是丢弃)max_length参数的类。或者让你的field类继承自forms.fields.CharField而不是forms.fields.Field.

或者,您完全覆盖该formfield方法以不添加该参数。这意味着您基本上需要绕过models.CharField.formfield实现并models.Field.formfield直接调用:

def formfield(self, **kwargs):
    defaults = {'form_class': fields.field}
    defaults.update(kwargs)
    return super(CharField, self).formfield(**defaults)

不一定是最优雅的解决方案,因为它依赖于许多内部实现细节,如特定的继承层次结构,所以准备检查这是否会随着每次 Django 版本更改而中断。


推荐阅读