如何使用默认管理员在我的自定义视图中使用的漂亮的 JavaScript 日期和时间小部件?
我浏览了 Django 表单文档,它简要提到了 django.contrib.admin.widgets,但我不知道如何使用它?
这是我想要应用的模板。
<form action="." method="POST"> <table> {% for f in form %} <tr> <td> {{ f.name }}</td> <td>{{ f }}</td> </tr> {% endfor %} </table> <input type="submit" name="submit" value="Add Product"> </form>
另外,我认为应该注意的是,我自己并没有真正为这个表单编写视图,我使用的是通用视图。这是来自 url.py 的条目:
(r'^admin/products/add/$', create_object, {'model': Product, 'post_save_redirect': ''}),
而且我对整个 Django/MVC/MTV 的事情都比较陌生,所以请放轻松…
随着时间的推移,这个答案越来越复杂,并且需要许多技巧,可能应该警告你不要这样做。它依赖于管理员未记录的内部实现细节,很可能在未来版本的 Django 中再次出现问题,而且实现起来并不比找到另一个 JS 日历小部件并使用它更容易。
也就是说,如果您决心完成这项工作,您必须执行以下操作:
为您的模型定义您自己的ModelForm子类(最好将其放在应用程序中的 forms.py 中),并告诉它使用AdminDateWidget// AdminTimeWidget(AdminSplitDateTime将“mydate”等替换为模型中的正确字段名称):
ModelForm
AdminDateWidget
AdminTimeWidget
AdminSplitDateTime
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_class': ProductForm
'model': Product
create_object
from my_app.forms import ProductForm
from my_app.models import Product
在模板的头部,包含{{ form.media }}以输出指向 Javascript 文件的链接。
{{ form.media }}
和 hacky 部分:管理日期/时间小部件假定 i18n JS 的东西已经加载,并且还需要 core.js,但不自动提供任何一个。因此,在您上面的模板中,{{ form.media }}您需要:
<script type="text/javascript" src="/my_admin/jsi18n/"></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/ - 您可以为您的设置更改它。理想情况下,您会使用上下文处理器将此值传递给您的模板,而不是对其进行硬编码,但这超出了此问题的范围。
ADMIN_MEDIA_PREFIX
这还需要手动将 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>