如何在我的自定义视图中使用默认管理员使用的漂亮的JavaScript日期和时间小部件?

我浏览了the Django forms documentation页,其中简短地提到了django.contri.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的future 版本中可能会再次中断,而且实现起来并不比找到另一个JS日历小部件并使用它更容易.

也就是说,如果你下定决心要做到这一点,以下是你必须做的:

  1. 为您的模型定义您自己的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()
    
  2. 将URLconf更改为pass 'form_class': ProductForm而不是'model': Product,将其转换为generic create_object视图(当然,这意味着from my_app.forms import ProductForm而不是from my_app.models import Product).

  3. 在模板的头部,包括{{ form.media }}以输出指向Javascript文件的链接.

  4. 麻烦的是:admin date/time小部件假定已经加载了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>

谢谢你的加入.

Django相关问答推荐

Django Form初始值不在呈现上起作用

创建用户/将用户登录到客户端服务器的标准OAuth/OIDC流程是什么?

Django REST序列化程序TO_REATION失败

Django:添加第二个';详细';用于检索额外信息的视图

访问默认的 django-allauth 登录和注册页面时出现 TemplateSyntaxError

在Django测试get方法中获取HttpResponseNotFound

从一个组中获取所有用户 - Django

DecimalField 验证错误,返回不正确的值 Django

QuerySet对象在bulk_update中没有属性pk

关于Django中批量保存对象的问题

模型中的外键

如何使用 django 发送 POST 请求?

django:manytomanyfield 和 through 如何出现在 admin 中?

Matplotlib - Tcl_AsyncDelete:异步处理程序被错误的线程删除?

Django post_save 在不覆盖模型 save() 的情况下防止递归

django 模板列表变量中的最后一个元素

升级到 Django 1.8 后提供的固定默认值

如何使用查询参数构造 Django 反向/url?

如何在 django 中仅获取表的特定列?

Django 将多个模型传递给一个模板