给出一组典型的模型:
# Application A from django.db import models class TypicalModelA(models.Model): the_date = models.DateField() # Application B from django.db import models class TypicalModelB(models.Model): another_date = models.DateField() ...
如何将所有 DateFields 的默认小部件更改为自定义MyDateWidget?
我问,因为我希望我的应用程序有一个jQueryUI datepicker用于输入日期.
我考虑过一个自定义字段,它使用我的自定义小部件扩展django.db.models.DateField.这是实施这种全面改变的最佳方式吗?这样的改变需要专门将一个特殊的MyDateField导入到每个模型中,这是一个劳动密集型,容易出现开发人员错误(即一些模型.DateField将会通过),在我看来似乎是不必要的重复工作.另一方面,我不喜欢修改可以被认为是规范版本的模型.DateField.
感谢思想和投入.
您可以在ModelForm
类上声明一个名为的属性formfield_callback
.这应该是一个将Django模型Field
实例作为参数的函数,并返回一个表单Field
实例以在表单中表示它.
然后,您要做的就是查看传入的模型字段是否为实例DateField
,如果是,则返回自定义字段/窗口小部件.如果没有,模型字段将具有一个名为的方法formfield
,您可以调用该方法返回其默认表单字段.
所以,像:
def make_custom_datefield(f): if isinstance(f, models.DateField): # return form field with your custom widget here... else: return f.formfield() class SomeForm(forms.ModelForm) formfield_callback = make_custom_datefield class Meta: # normal modelform stuff here...
这篇文章曾多次帮助过我.
它的内容涉及覆盖ModelForm的__init__
方法,然后调用超类的__init__
方法,然后单独调整字段.
class PollForm(forms.ModelForm): def __init__(self, *args, **kwargs): super(PollForm, self).__init__(*args, **kwargs) self.fields['question'].widget = forms.Textarea() class Meta: model = Poll
这种方法看起来可能比Vasil更复杂,但它提供了额外的好处,即能够精确覆盖字段上的任何属性,而无需通过重新声明来重置任何其他属性.
更新:建议的方法可以推广到更改所有日期字段而不严格键入每个名称:
from django.forms import fields as formfields from django.contrib.admin import widgets class PollForm(forms.ModelForm): def __init__(self, *args, **kwargs): super(PollForm, self).__init__(*args, **kwargs) for field_name in self.fields: field = self.fields[field_name] if isinstance(field, formfields.DateField): field.widget = widgets.AdminDateWidget() class Meta: model = Poll
这为我工作的python3
,并django 1.11
好吧,制作一个自定义模型字段只是为了改变它的默认表单小部件并不是一个明显的起点.
您可以创建自己的表单窗口小部件并覆盖表单中的字段,在Soviut的答案中指定您自己的窗口小部件.
还有一个更短的方式:
class ArticleForm(ModelForm): pub_date = DateField(widget=MyDateWidget()) class Meta: model = Article
有一个如何编写表单小部件的例子,它位于Django的表单包中.这是一个有3个下拉菜单的日期选择器.
当我只想将一些JavaScript添加到标准HTML输入元素时,我通常会做的就是保持原样并通过稍后使用JavaScript引用它来修改它.您可以轻松捕获Django生成的输入字段的ID的命名约定.
您还可以在窗体中覆盖窗口小部件时为窗口小部件提供类.然后用类名用jQuery捕获它们.