随着时间的推移,这个答案越来越复杂,并且需要许多技巧,可能应该警告你不要这样做。它依赖于管理员未记录的内部实现细节,很可能在未来版本的 Django 中再次出现问题,而且实现起来并不比找到另一个 JS 日历小部件并使用它更容易。
也就是说,如果您决心完成这项工作,您必须执行以下操作:
为您的模型定义您自己的ModelForm
子类(最好将其放在应用程序中的 forms.py 中),并告诉它使用AdminDateWidget
// AdminTimeWidget
(AdminSplitDateTime
将“mydate”等替换为模型中的正确字段名称):
from django import forms
from my_app.models import Product
from django.contrib.admin import widgets
class ProductForm(forms.ModelForm):
class Meta:
model = Product
def __init__(self, *args, **kwargs):
super(ProductForm, self).__init__(*args, **kwargs)
self.fields['mydate'].widget = widgets.AdminDateWidget()
self.fields['mytime'].widget = widgets.AdminTimeWidget()
self.fields['mydatetime'].widget = widgets.AdminSplitDateTime()
将您的 URLconf 更改为传递'form_class': ProductForm
而不是传递'model': Product
给通用create_object
视图(当然,这意味着from my_app.forms import ProductForm
而不是from my_app.models import Product
)。
在模板的头部,包含{{ form.media }}
以输出指向 Javascript 文件的链接。
还有最棘手的部分:管理日期/时间小部件假定 i18n JS 内容已加载,并且还需要 core.js,但不会自动提供任何一个。因此,在您上面的模板中,{{ form.media }}
您需要:
<script type="text/javascript" src="/my_admin/jsi18n/"></script>
<script type="text/javascript" src="/media/admin/js/core.js"></script>
您可能还希望使用以下管理 CSS(感谢Alex提到这一点):
<link rel="stylesheet" type="text/css" href="/media/admin/css/forms.css"/>
<link rel="stylesheet" type="text/css" href="/media/admin/css/base.css"/>
<link rel="stylesheet" type="text/css" href="/media/admin/css/global.css"/>
<link rel="stylesheet" type="text/css" href="/media/admin/css/widgets.css"/>
这意味着 Django 的管理媒体 ( ADMIN_MEDIA_PREFIX
) 位于 /media/admin/ - 您可以为您的设置更改它。理想情况下,您会使用上下文处理器将此值传递给您的模板,而不是对其进行硬编码,但这超出了此问题的范围。
这还需要手动将 URL /my_admin/jsi18n/ 连接到 django.views.i18n.javascript_catalog 视图(如果您不使用 I18N,则为 null_javascript_catalog)。您必须自己执行此操作,而不是通过管理应用程序,因此无论您是否登录到管理员都可以访问它(感谢Jeremy指出这一点)。URLconf 的示例代码:
(r'^my_admin/jsi18n', 'django.views.i18n.javascript_catalog'),
最后,如果您使用的是 Django 1.2 或更高版本,您需要在模板中添加一些额外的代码来帮助小部件找到它们的媒体:
{% load adminmedia %} /* At the top of the template. */
/* In the head section of the template. */
<script type="text/javascript">
window.__admin_media_prefix__ = "{% filter escapejs %}{% admin_media_prefix %}{% endfilter %}";
</script>
感谢lupefiasco的添加。