当你在Django管理页面注册一个模型时,它会自动将模型的每个字段匹配到一个widget上,这样你就可以在Django管理面板上轻松地输入数据并管理模型的实例。大多数时候,默认的widget已经足够了,但在某些情况下,它们可能不是最适合你的特定需求。
例如,假设你的一个模型有一个代表用户出生日期的DateField,又假设由于某种原因,你需要经常从管理面板创建用户实例,也许是为了测试。
那么如果你想输入现实的数据,默认的DatePicker可能会很不方便,因为你不能直接输入年份,必须逐月浏览才能到达你想要的年份。
在这种情况下,你可能想改变小部件来挑选日期。如果在做了一些研究之后,你没有找到关于如何做到这一点的明确解释,不要担心,因为这不仅很容易,而且我将在这篇文章中指导你完成!让我们开始吧。
设置
在这个例子中,我将假设你已经安装了python和Django,并且准备好了一个项目,你将对其进行这些改动。
在我的例子中,我做了一个非常简单的项目,叫做project,只有一个叫做customers的应用程序和以下布局:

在管理页面上注册了模型后,当我们试图从管理面板上创建/修改一个新的实例时,它看起来就像这样:
正如你所看到的,从几年前挑选一个日期已经非常繁琐了,所以试想一下,搜索一个生日会有多困难。
我们现在要把这个部件换成一个新的部件,使浏览年份更容易,更适合处理特定的出生日期。
改变小工具
我们将定义一个新的Datepicker,首先是一个具有我们想要使用的特定日期格式的通用控件。然后,我们将创建一个更具体的,继承自它的日期,并且不允许用户输入那些没有意义的生日(即未来的日期)。
这一切都归结于小组件使用的日期格式--默认小组件执行的日期格式是日-月-年。
我们新的CustomDatePickerWidget将要求使用年-月-日期格式。为了定义这些新的部件,让我们创建一个新的文件widgets.py,在我的例子中,我将在project/project/widgets.py创建,代码如下。
- 在attrs中添加class: form-control和type: date,这对确保显示一个日历小部件很重要,我们可以在其中选择一个日期(如果我们不这样做,在表单中显示的这个字段的输入将是一个纯文本)。
- 如果没有提供其他的格式作为参数,则将%Y-%m-%d设置为该类的格式属性。
然后我们就简单地调用父类的构造函数来处理剩下的事情。
有了这个,我们已经有了一个小组件,解决了我们主要关心的问题,即以一种方便的方式浏览年份,你可以将其子类化为更具体的属性,以更好地处理你的用例。
对于我们的客户模型,因为我们将处理出生日期,我们也想确保没有未来的日期将被用作输入,所以在同一文件中,就在这个类下我们将定义。
正如你所看到的,在构造函数中我们更新了attrs,指定max为date.day()。
现在,有了我们新的部件的定义,我们只需要在我们在管理页面注册模型的地方使用它来覆盖默认的。
在project/customers/admin.py中,我已经有一个CustomerAdmin,它是我用来在管理页面上注册客户模型的类。在我的例子中,它是空的,所以我打算添加以下代码。
我们在这里做的是导入DatePicker,并将其作为formfield_overrides中的widget的值,如代码中所示。
就这样了!现在我们可以以更舒适的方式输入出生日期值,而不是无休止地滚动月数!
总结
在这篇博文中,我们讨论了如何为Django创建一个新的自定义DatePicker,以及如何将其作为Django管理页面的默认DatePicker。
我希望你喜欢它并觉得它很有用,感谢你的阅读,并请继续关注更多类似的内容!