以自定义形式使用 Django 时间/日期小部件 [英] Using Django time/date widgets in custom form

查看:30
本文介绍了以自定义形式使用 Django 时间/日期小部件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

How can I use the nifty JavaScript date and time widgets that the default admin uses with my custom view?

我浏览了Django 表单文档,它简要提到django.contrib.admin.widgets,但是不知道怎么用?

I have looked through the Django forms documentation, and it briefly mentions django.contrib.admin.widgets, but I don't know how to use it?

这是我想要应用的模板.

Here is my template that I want it applied on.

<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 的条目:

Also, I think it should be noted that I haven't really written a view up myself for this form, I am using a generic view. Here is the entry from the url.py:

(r'^admin/products/add/$', create_object, {'model': Product, 'post_save_redirect': ''}),

而且我对整个 Django/MVC/MTV 的东西都很陌生,所以请放轻松...

And I am relevantly new to the whole Django/MVC/MTV thing, so please go easy...

推荐答案

随着时间的推移,这个答案变得越来越复杂,并且需要很多技巧,可能应该提醒您不要这样做.它依赖于未记录的管理员内部实现细节,很可能在未来版本的 Django 中再次崩溃,而且实现起来并不比找到另一个 JS 日历小部件并使用它更容易.

The growing complexity of this answer over time, and the many hacks required, probably ought to caution you against doing this at all. It's relying on undocumented internal implementation details of the admin, is likely to break again in future versions of Django, and is no easier to implement than just finding another JS calendar widget and using that.

也就是说,如果您决心完成这项工作,您必须这样做:

That said, here's what you have to do if you're determined to make this work:

  1. 为你的模型定义你自己的 ModelForm 子类(最好把它放在你的应用程序的 forms.py 中),并告诉它使用 AdminDateWidget/AdminTimeWidget/AdminSplitDateTime(用模型中的正确字段名称替换mydate"等):

  1. Define your own ModelForm subclass for your model (best to put it in forms.py in your app), and tell it to use the AdminDateWidget / AdminTimeWidget / AdminSplitDateTime (replace 'mydate' etc with the proper field names from your model):

 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).

  • Change your URLconf to pass 'form_class': ProductForm instead of 'model': Product to the generic create_object view (that'll mean from my_app.forms import ProductForm instead of from my_app.models import Product, of course).

    在模板的头部,包含 {{ form.media }} 以输出到 Javascript 文件的链接.

    In the head of your template, include {{ form.media }} to output the links to the Javascript files.

    还有一个棘手的部分:管理日期/时间小部件假定已加载 i18n JS 内容,并且还需要 core.js,但不会自动提供任何一个.因此,在 {{ form.media }} 上方的模板中,您需要:

    And the hacky part: the admin date/time widgets presume that the i18n JS stuff has been loaded, and also require core.js, but don't provide either one automatically. So in your template above {{ form.media }} you'll need:

     <script type="text/javascript" src="/my_admin/jsi18n/"></script>
     <script type="text/javascript" src="/media/admin/js/core.js"></script>
    

  • 您可能还希望使用以下管理 CSS(感谢 亚历克斯 提到这一点):

    You may also wish to use the following admin CSS (thanks Alex for mentioning this):

        <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/- 您可以为您的设置更改它.理想情况下,您应该使用上下文处理器将此值传递给您的模板,而不是对其进行硬编码,但这超出了本问题的范围.

    This implies that Django's admin media (ADMIN_MEDIA_PREFIX) is at /media/admin/ - you can change that for your setup. Ideally you'd use a context processor to pass this values to your template instead of hardcoding it, but that's beyond the scope of this question.

    这还需要将 URL/my_admin/jsi18n/手动连接到 django.views.i18n.javascript_catalog 视图(如果您不使用 I18N,则为 null_javascript_catalog).您必须自己执行此操作而不是通过管理应用程序,因此无论您是否登录到管理员都可以访问它(感谢 Jeremy 指出这一点).URLconf 的示例代码:

    This also requires that the URL /my_admin/jsi18n/ be manually wired up to the django.views.i18n.javascript_catalog view (or null_javascript_catalog if you aren't using I18N). You have to do this yourself instead of going through the admin application so it's accessible regardless of whether you're logged into the admin (thanks Jeremy for pointing this out). Sample code for your URLconf:

    (r'^my_admin/jsi18n', 'django.views.i18n.javascript_catalog'),
    

    最后,如果您使用的是 Django 1.2 或更高版本,您需要在模板中添加一些额外的代码来帮助小部件找到它们的媒体:

    Lastly, if you are using Django 1.2 or later, you need some additional code in your template to help the widgets find their media:

    {% 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.

    这篇关于以自定义形式使用 Django 时间/日期小部件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆