【问题标题】:Django calendar widget in a custom form自定义表单中的 Django 日历小部件
【发布时间】:2011-07-23 21:43:08
【问题描述】:

我正在尝试将日历日期输入添加到我的一个表单中。 Django 在其管理页面上使用了一个很棒的日历小部件,但我不知道如何将它添加到自定义表单中。

我在这里发现了一些关于同一主题的其他问题,但它们似乎都已过时、复杂且不起作用。

有没有办法将 Django 的内置日历小部件包含到我的一个表单中?

【问题讨论】:

  • 目前我发现的最简单快捷的方法是使用forms.widgets.DateInput
  • 参见下面的this answer,它是最新的,而且非常简单。但是,请注意,这提供了 3 个下拉菜单(年、月、日),而不仅仅是一个日历框……IMO 有点烦人。
  • 我设法让它在 Django 2.0.2 上运行。请参阅此链接上的我的答案。 Django 2 AdminDateWidget

标签: django django-forms


【解决方案1】:

考虑使用 Django 中内置的普通“SelectDateWidget”,而不是 Admin 小部件:https://docs.djangoproject.com/en/stable/ref/forms/widgets/#selectdatewidget

【讨论】:

  • 这是更好的现代方法。其他答案现在太旧了。
  • 完美!那么唯一需要的就是写在 Form 类定义中:Date = forms.DateField(widget = forms.SelectDateWidget)
  • 有用的插件,用于选择人们可以选择的年份范围(例如从 2017 年到 2020 年):widget = SelectDateWidget(years=range(2017, 2020))
  • 专业版 - 非常简单。缺点 - 非常丑陋。根本不传达一个月中的哪一天。到底为什么 Django 会附带一个可行的日历小部件,但它很难集成到您的应用中?
【解决方案2】:

django-admin 使用的所有小部件都在 django/contrib/admin/widgets.py 文件中。只需将其用作表单中的常用小部件即可。你想要的是 AdminDateWidget。

from django.contrib.admin.widgets import AdminDateWidget
from django.forms.fields import DateField

class MyForm(Form):
    my_field = DateField(widget=AdminDateWidget)

这将创建一个带有日历的日期选择器。您可以尝试通过扩展它来自定义它以满足您的需要,或者从 AdminDateWidget 的灵感从头开始创建一个新的小部件。

【讨论】:

  • 当我尝试上面的代码时,我得到一个错误,DateField 没有定义。我也试过forms.DateField,但最后我得到了一个txt字段。
  • 我的模板似乎没有在顶部输出所需的JS文件。我的模板是否需要另一个标签来包含这些标签?
  • 你应该导入 DateField from django.forms.fields import DateField 我相信你已经明白了。是的,您必须在模板{% load i18n %} 中使用一个标签才能加载javascript。我使用了 admin 的 base.html 模板,所以我不必导入所有需要的文件。
【解决方案3】:

感谢 Dave S. 和有关此主题的许多旧帖子,我想通了。我的成功方法:

创建自定义表单。

在顶部,使用from django.contrib.admin.widgets import AdminDateWidget 导入管理小部件。然后,在您想使用日期小部件时使用my_field = DateField(widget = AdminDateWidget) 添加表单的不同字段。

创建您的表单模板

将以下内容放在顶部以包含适当的 css/js 文件:

{% load i18n admin_modify adminmedia %}
{% block extrahead %}{{ block.super }}
<link rel="stylesheet" type="text/css" href="{% admin_media_prefix %}css/base.css" />
<link rel="stylesheet" type="text/css" href="{% admin_media_prefix %}css/widgets.css" />
<script type="text/javascript" src="/jsi18n/"></script>
<script type="text/javascript" src="{% admin_media_prefix %}js/core.js"></script>
{{ form.media }}
{% endblock %}

注意:您不一定需要所有这些,这取决于您的 Django 版本以及您如何实现表单字段。这就是我发现我需要使用这些小部件的原因。

现在只需像平常一样输出您的表单,JS 应该会自动将其转换为日期字段。享受吧!

【讨论】:

  • 如果 jsi18n 存在于其他地方,那么可以这样做: {% url 'admin:jsi18n' as jsi18nurl %} (对于较旧的 Django 版本,您可能还需要 {% load url from future %})
  • 为了在管理员中完全工作,您还应该将这些 js 文件添加到与 core.js 一起的标题中
【解决方案4】:

您可以通过表单小部件“SelectDateWidget()”来执行此操作,如下例所示:

class MyForm(forms.Form):

        start_date=forms.DateField(widget = forms.SelectDateWidget())
        end_date=forms.DateField(widget = forms.SelectDateWidget())

【讨论】:

    【解决方案5】:

    这基本上是Using Django time/date widgets in custom form的复制品。

    @Dave S 和 @MrGlass 已经给出了答案,但对于 Django 1.2 及更高版本,还需要这有助于 JavaScript 找到管理媒体:

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

    (来自Carl Meyer's answer

    【讨论】:

      【解决方案6】:

      使用名为 NumberInput 的 django 表单小部件作为 Django 中任何日期字段或日期时间字段的小部件 这将呈现基本的 HTML NumberInput 字段供用户选择。我刚刚对此进行了测试,如果您将其视为 python datetime 对象,它会在后端收到日期时起作用

      from django.forms.widgets import NumberInput
      
      # label and required are both optional arguments  
      date_input = forms.DateTimeField(label="Date", required=True, widget=NumberInput(attrs={'type':'date'}))
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-04-03
        • 1970-01-01
        • 2011-06-12
        • 1970-01-01
        • 2012-07-18
        • 1970-01-01
        • 2011-06-10
        • 1970-01-01
        相关资源
        最近更新 更多