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

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

问题描述

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



我已经查看了 Django表单文档,并简要介绍django.contrib.admin.widgets,但我不知道如何使用它?



这是我想要应用的模板。

 code>< form action =。方法= POST > 
< table>
{%for form in form%}
< tr> < TD> {{f.name}}< / td> < td> {{f}}< / td> < / TR>
{%endfor%}
< / table>
< input type =submitname =submitvalue =添加产品>
< / form>

另外,我想应该注意的是,我还没有真正为自己编写一个查看形式,我正在使用通用视图。以下是url.py中的条目:

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

而且我相当新整个Django / MVC / MTV的东西,所以请轻松...

解决方案

随着时间的推移,所需的许多黑客,大概应该提醒你不要这样做。它依赖于管理员的未记录的内部实现细节,很可能会在将来的Django版本中再次破解,而不仅仅是找到另一个JS日历窗口小部件并使用它,而不会实现。


$ b $那么说,如果你决定做这个工作,这就是你要做的事情:


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

     从django导入表单
    from my_app.models import产品
    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.fi elds ['mydate']。widget = widgets.AdminDateWidget()
    self.fields ['mytime']。widget = widgets.AdminTimeWidget()
    self.fields ['mydatetime']。widget = widgets .AdminSplitDateTime()


  2. 更改您的URLconf以传递'form_class':ProductForm而不是'model ':产品到通用的create_object视图(这意味着from my_app.forms import ProductForm而不是from my_app.models import Product,当然)。


  3. 在您的模板的头部,包括{{form.media}}输出到Javascript文件的链接。


  4. :管理日期/时间小部件假设i18n JS的东西已经加载,并且还需要core.js,但是不要自动提供。所以在{{form.media}}上面的模板中,您需要:

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

    您还可以使用以下管理CSS(谢谢 Alex 提及此):

     < link rel =stylesheettype =text / csshref =/ media / admin / css / forms.css/> 
    < link rel =stylesheettype =text / csshref =/ media / admin / css / base.css/>
    < link rel =stylesheettype =text / csshref =/ media / admin / css / global.css/>
    < link rel =stylesheettype =text / csshref =/ 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%} / *在模板的顶部。 * / 

/ *在模板的头部。 * /
< script type =text / javascript>
window .__ admin_media_prefix__ ={%filter escapejs%} {%admin_media_prefix%} {%endfilter%};
< / script>

感谢 lupefiasco 为此添加。


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

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>

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': ''}),

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

解决方案

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

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

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

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

    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"/>
    

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.

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'),

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>

Thanks lupefiasco for this addition.

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

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