python - 如何防止 Django Admin 覆盖自定义字段的自定义小部件?

标签 python django django-forms django-admin

我有一个模型字段、一个表单字段和一个在应用程序中使用的小部件。代码的细节并不重要。关键是该字段以常规形式正确呈现,但在管理中被覆盖。

以下是该字段的一些伪代码:

class SandwichWidget(forms.Widget):
    template_name = 'sandwichfield/widgets/sandwichfield.html'

    def __init__(self, attrs=None, date_format=None, time_format=None):
        widgets = (
            NumberInput(),
            Select(choices=FILLING_CHOICES),
            NumberInput(),
        )
        super(SandwichWidget, self).__init__(widgets, attrs)

    def decompress(self, value):
        if value:
            value = Sandwich(value)
            return [
                value.top,
                value.middle,
                value.bottom
            ]
        return [None, None, None]


class SandwichFormField(forms.MultiValueField):
    widget = SandwichWidget

    def __init__(self, input_date_formats=None, input_time_formats=None, *args, **kwargs):
        fields = (
            forms.IntegerField(),
            forms.CharField(),
            forms.IntegerField(),
        )
        super(SandwichFormField, self).__init__(fields, *args, **kwargs)


class SandwichField(models.PositiveIntegerField):

    def get_internal_type(self):
        return 'IntegerField'

    def formfield(self, *args, **kwargs):
        defaults={'form_class': SandwichFormField}
        defaults.update(kwargs)
        return super(SandwichField, self).formfield(*args, **defaults)

这显然是因为 this line in django/contrib/admin/options.py 发生的它指定 models.IntegerField 的覆盖应该是 widgets.AdminIntegerFieldWidget。因为 models.PositiveIntegerField 继承自 models.IntegerField,并且因为 line 181循环遍历该字段的所有子类,似乎没有办法阻止该小部件在管理中被覆盖。

这是一个真正的问题,因为我在整个网站和整个管理中使用这个自定义字段及其自定义小部件,并且我不想为 override_fields 输入自定义值每次我想使用该字段时。理想情况下,开发人员应该能够使用自定义字段,而不必每次都提供自定义管理员。

目前我正在继承 forms.PositiveIntegerField 因为当从数据库存储和检索时,它是一个正整数,并且我想利用所有已经到位的编码来进行处理正整数值。

目前看来唯一的解决方案是将我的字段更改为从models.Field继承,然后复制并粘贴所有PositiveIntegerField和 django 代码中的 IntegerField 功能。有替代方案吗?

当然,我总是可以让我的表单字段忽略发送给它的任何小部件并始终使用自定义小部件,但是当我主动想要覆盖小部件时,这会引发一个问题,这绝对可以发生。我只是不想让管理员覆盖我的小部件。

最佳答案

试试这个(我将底部的第二行添加到您的代码中):

class SandwichField(models.PositiveIntegerField):

    def formfield(self, *args, **kwargs):
        defaults={'form_class': SandwichFormField}
        defaults.update(kwargs)
        defaults['widget'] = SandwichFormField.widget
        return super(SandwichField, self).formfield(*args, **defaults)

管理代码正在向您传递一个具有自己的小部件的 kwargs,因此您有 覆盖它。

关于python - 如何防止 Django Admin 覆盖自定义字段的自定义小部件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53641689/

相关文章:

python - 如何在类中迭代 `dict` 就像只引用 `dict` 一样?

python - 如何限制 Django 应用程序中显示的项目数量

django - 使用 Django 的 ORM 进行复杂的 M2M 过滤

使用 Django 时出现 Javascript 验证错误

django - Django 表单集中每个表单的初始数据不同

python - 保留 undefined variable

python - 绘制海量networkx图: Array too big

python - 如何根据本地位置/旋转在 OpenGL 中移动/旋转对象

django - 重定向到管理员保存

python - Django目录上传获取子目录名