将 Django 的默认小部件更改为自定义小部件

gue*_*tli 5 forms django monkeypatching

我的用例:我想使用不同的 DateInput。但我想减少代码重复。我希望所有没有明确需要不同 DateInput 小部件的表单都使用我的自定义小部件。

没有猴子补丁的情况下有什么改变可以解决这个问题吗?

例子

模型.py:

class MyModel(models.Model):
    date=models.DateField()
Run Code Online (Sandbox Code Playgroud)

形式.py:

class MyForm(forms.ModelForm):
    class Meta:
        model=MyModel
Run Code Online (Sandbox Code Playgroud)

上面的代码应该使用我的自定义小部件。我不想更改上面的 models.py 和 forms.py,因为有很多。

aww*_*ter 3

不幸的是,我认为您无法使用上面列出的确切代码来实现此功能。

如果不破解 django,基本上有两个部分。第一个是创建自定义表单字段,第二个是将自定义模型字段默认为新创建的表单字段。

要创建自定义表单字段,您可以覆盖现有的 django forms.DateField 并更新小部件。

# form_fields.py
from django.forms import DateField
from myapp.widgets import MyWidget

class MyDateFormField(DateField):
    widget = MyWidget
Run Code Online (Sandbox Code Playgroud)

创建表单字段后,您必须覆盖 django 模型字段以默认为新表单字段

# fields.py
from django.db.models import DateField
from myapp.form_fields import MyDateFormField

class MyDateField(DateField):
    def formfield(self, **kwargs):
        defaults = {'form_class': MyDateFormField}
        defaults.update(kwargs)
        return super(DateField, self).formfield(**defaults)
Run Code Online (Sandbox Code Playgroud)

然后,您将拥有自定义模型字段,您需要稍微更改代码才能使用。

from myapp.fields import MyDateField

class MyModel(models.Model):
    date=MyDateField()
Run Code Online (Sandbox Code Playgroud)

这并不完全是您所要求的(必须更改模型字段),但希望这能让您朝着正确的方向前进。