当前位置:  开发笔记 > 编程语言 > 正文

以自定义形式使用Django时间/日期小部件

如何解决《以自定义形式使用Django时间/日期小部件》经验,为你挑选了8个好方法。

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

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

这是我想要应用的模板.

{% for f in form %} {% endfor %}
{{ f.name }} {{ f }}

此外,我认为应该注意的是,我没有真正为自己的表单编写视图,我使用的是通用视图.这是来自url.py的条目:

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

而且我对整个Django/MVC/MTV事物都是新手,所以请轻松一点......



1> Carl Meyer..:

随着时间的推移,这个答案越来越复杂,以及所需的许多黑客,可能应该提醒你不要这样做.它依赖于管理员的未记录的内部实现细节,可能会在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':产品到通用create_object视图(这意味着"来自my_app.forms导入ProductForm"而不是"来自my_app.models导入产品",当然).

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

    而hacky部分:管理日期/时间小部件假设已经加载了i18n JS的东西,并且还需要core.js,但是不要自动提供任何一个.因此,在{{form.media}}上方的模板中,您需要:

    
    
    

    您可能还希望使用以下管理CSS(感谢Alex提及此内容):

    
    
    
    
    

这意味着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. */

感谢lupefiasco的加入.


最有帮助的帖子在线发布,但最终得到了日期/时间小部件,并且填充字段现在要将其取出,因为尽管在表单字段中需要= False,它现在显示消息"输入有效的日期/时间".如果我把它留空,我的不需要的字段.回到jquery为我.

2> zgoda..:

由于解决方案是hackish,我认为使用自己的日期/时间小部件与一些JavaScript是更可行的.


我同意.几个月前,我尝试用我的django项目做这件事.我最终放弃了,只是添加了自己的jQueryUI.花了10分钟才完成它.
为了记录,我同意,我赞成这个答案,我从来没有在生产网站的答案中实际使用过该技术;-)

3> 小智..:

是的,我最终覆盖了/ admin/jsi18n/url.

这是我在urls.py中添加的内容.确保它在/ admin/url之上

    (r'^admin/jsi18n', i18n_javascript),

这是我创建的i18n_javascript函数.

from django.contrib import admin
def i18n_javascript(request):
  return admin.site.i18n_javascript(request)



4> monkut..:

我发现自己经常引用这篇文章,并发现文档定义了一种稍微不那么粗暴的方式来覆盖默认小部件.

(无需覆盖ModelForm的__init__方法)

但是,你还需要像Carl提到的那样适当地连接你的JS和CSS.

forms.py

from django import forms
from my_app.models import Product
from django.contrib.admin import widgets                                       


class ProductForm(forms.ModelForm):
    mydate = forms.DateField(widget=widgets.AdminDateWidget)
    mytime = forms.TimeField(widget=widgets.AdminTimeWidget)
    mydatetime = forms.SplitDateTimeField(widget=widgets.AdminSplitDateTime)

    class Meta:
        model = Product

参考字段类型以查找默认表单字段.


我不同意这种方法不那么苛刻.它看起来更好,当然,但是你完全覆盖了模型表单生成的表单字段,这也可以删除模型字段中的选项,比如help_text.覆盖__init__只会更改窗口小部件,并保留表单字段的其余部分.

5> 小智..:

我的1.4版本的头代码(一些新的和一些删除)

{% block extrahead %}















{% endblock %}


真棒.我从过去的两周开始尝试这个,这对我很有帮助

6> mshafrir..:

从Django 1.2 RC1开始,如果您正在使用Django管理日期选择器widge技巧,则必须将以下内容添加到您的模板中,否则您将看到通过"/ missing-admin-media-prefix引用的日历图标URL /".

{% load adminmedia %} /* At the top of the template. */

/* In the head section of the template. */



7> Alex. S...:

作为对Carl Meyer的回答的补充,我想评论您需要将该标题放在模板中的某个有效块(标题内)中.

{% block extra_head %}










{{ form.media }}

{% endblock %}



8> Dennis Kioko..:

如果上述失败,下面也将作为最后的手段

class PaymentsForm(forms.ModelForm):
    class Meta:
        model = Payments

    def __init__(self, *args, **kwargs):
        super(PaymentsForm, self).__init__(*args, **kwargs)
        self.fields['date'].widget = SelectDateWidget()

与...一样

class PaymentsForm(forms.ModelForm):
    date = forms.DateField(widget=SelectDateWidget())

    class Meta:
        model = Payments

把它放在你的forms.py中 from django.forms.extras.widgets import SelectDateWidget

推荐阅读
云聪京初瑞子_617
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有