{% for f in form %}

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

python django

105518 观看

14回复

4233 作者的声誉

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

我查看了Django表单文档,并简要提到了django.contrib.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事物都是新手,所以请轻松一点......

作者: Josh Hunt 的来源 发布者: 2008 年 9 月 1 日

回应 (14)


153

60321 作者的声誉

决定

随着时间的推移,这个答案越来越复杂,以及所需的许多黑客,可能应该提醒你不要这样做。它依赖于管理员的未记录的内部实现细节,可能会在Django的未来版本中再次破解,并且不仅仅是找到另一个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以传递'form_class':ProductForm而不是'model':产品到通用create_object视图(这意味着“来自my_app.forms导入ProductForm”而不是“来自my_app.models导入产品”,当然)。

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

  4. 而hacky部分:管理日期/时间小部件假设已经加载了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>

感谢lupefiasco的加入。

作者: Carl Meyer 发布者: 02.09.2008 06:10

63

11226 作者的声誉

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

作者: zgoda 发布者: 16.09.2008 01:39

12

0 作者的声誉

是的,我最终覆盖了/ 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)
作者: Jeremy 发布者: 02.01.2009 10:53

7

52044 作者的声誉

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

{% block extra_head %}

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

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

{{ form.media }}

{% endblock %}
作者: Alex. S. 发布者: 05.04.2009 08:02

11

26090 作者的声誉

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

无需覆盖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

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

作者: monkut 发布者: 08.09.2009 06:42

1

111 作者的声誉

SplitDateTime的更新解决方案和解决方法,其中required = False

forms.py

from django import forms

class SplitDateTimeJSField(forms.SplitDateTimeField):
    def __init__(self, *args, **kwargs):
        super(SplitDateTimeJSField, self).__init__(*args, **kwargs)
        self.widget.widgets[0].attrs = {'class': 'vDateField'}
        self.widget.widgets[1].attrs = {'class': 'vTimeField'}  


class AnyFormOrModelForm(forms.Form):
    date = forms.DateField(widget=forms.TextInput(attrs={'class':'vDateField'}))
    time = forms.TimeField(widget=forms.TextInput(attrs={'class':'vTimeField'}))
    timestamp = SplitDateTimeJSField(required=False,)

form.html

<script type="text/javascript" src="/admin/jsi18n/"></script>
<script type="text/javascript" src="/admin_media/js/core.js"></script>
<script type="text/javascript" src="/admin_media/js/calendar.js"></script>
<script type="text/javascript" src="/admin_media/js/admin/DateTimeShortcuts.js"></script>

urls.py

(r'^admin/jsi18n/', 'django.views.i18n.javascript_catalog'),
作者: Samuel Adam 发布者: 02.12.2009 02:29

5

469 作者的声誉

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

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

作者: Dennis Kioko 发布者: 07.03.2010 04:09

10

2592 作者的声誉

从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. */
<script type="text/javascript">
window.__admin_media_prefix__ = "{% filter escapejs %}{% admin_media_prefix %}{% endfilter %}";
</script>
作者: mshafrir 发布者: 12.05.2010 11:03

3

1489 作者的声誉

如何只为您的窗口小部件分配一个类,然后将该类绑定到JQuery datepicker?

Django forms.py:

class MyForm(forms.ModelForm):

  class Meta:
    model = MyModel

  def __init__(self, *args, **kwargs):
    super(MyForm, self).__init__(*args, **kwargs)
    self.fields['my_date_field'].widget.attrs['class'] = 'datepicker'

还有一些用于模板的JavaScript:

  $(".datepicker").datepicker();
作者: trubliphone 发布者: 04.02.2012 06:50

10

101 作者的声誉

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

{% block extrahead %}

<link rel="stylesheet" type="text/css" href="{{ STATIC_URL }}admin/css/forms.css"/>
<link rel="stylesheet" type="text/css" href="{{ STATIC_URL }}admin/css/base.css"/>
<link rel="stylesheet" type="text/css" href="{{ STATIC_URL }}admin/css/global.css"/>
<link rel="stylesheet" type="text/css" href="{{ STATIC_URL }}admin/css/widgets.css"/>

<script type="text/javascript" src="/admin/jsi18n/"></script>
<script type="text/javascript" src="{{ STATIC_URL }}admin/js/core.js"></script>
<script type="text/javascript" src="{{ STATIC_URL }}admin/js/admin/RelatedObjectLookups.js"></script>
<script type="text/javascript" src="{{ STATIC_URL }}admin/js/jquery.js"></script>
<script type="text/javascript" src="{{ STATIC_URL }}admin/js/jquery.init.js"></script>
<script type="text/javascript" src="{{ STATIC_URL }}admin/js/actions.js"></script>
<script type="text/javascript" src="{{ STATIC_URL }}admin/js/calendar.js"></script>
<script type="text/javascript" src="{{ STATIC_URL }}admin/js/admin/DateTimeShortcuts.js"></script>

{% endblock %}
作者: Romamo 发布者: 12.07.2012 07:06

0

71 作者的声誉

在Django 10. myproject / urls.py中:在urlpatterns的开头

  from django.views.i18n import JavaScriptCatalog

urlpatterns = [
    url(r'^jsi18n/$', JavaScriptCatalog.as_view(), name='javascript-catalog'),
.
.
.]

在我的template.html中:

{% load staticfiles %}

    <script src="{% static "js/jquery-2.2.3.min.js" %}"></script>
    <script src="{% static "js/bootstrap.min.js" %}"></script>
    {# Loading internazionalization for js #}
    {% load i18n admin_modify %}
    <script type="text/javascript" src="{% url 'javascript-catalog' %}"></script>
    <script type="text/javascript" src="{% static "/admin/js/jquery.init.js" %}"></script>

    <link rel="stylesheet" type="text/css" href="{% static "/admin/css/base.css" %}">
    <link rel="stylesheet" type="text/css" href="{% static "/admin/css/forms.css" %}">
    <link rel="stylesheet" type="text/css" href="{% static "/admin/css/login.css" %}">
    <link rel="stylesheet" type="text/css" href="{% static "/admin/css/widgets.css" %}">



    <script type="text/javascript" src="{% static "/admin/js/core.js" %}"></script>
    <script type="text/javascript" src="{% static "/admin/js/SelectFilter2.js" %}"></script>
    <script type="text/javascript" src="{% static "/admin/js/admin/RelatedObjectLookups.js" %}"></script>
    <script type="text/javascript" src="{% static "/admin/js/actions.js" %}"></script>
    <script type="text/javascript" src="{% static "/admin/js/calendar.js" %}"></script>
    <script type="text/javascript" src="{% static "/admin/js/admin/DateTimeShortcuts.js" %}"></script>
作者: Jose Luis Quichimbo 发布者: 09.10.2016 05:39

1

11 作者的声誉

我使用它,它很棒,但我有2个模板问题:

  1. 我在模板中看到每个字段的日历图标两次
  2. 对于TimeField,我有' 输入有效日期。

    这是表单的屏幕截图

models.py

from django.db import models
    name=models.CharField(max_length=100)
    create_date=models.DateField(blank=True)
    start_time=models.TimeField(blank=False)
    end_time=models.TimeField(blank=False)

forms.py

from django import forms
from .models import Guide
from django.contrib.admin import widgets

class GuideForm(forms.ModelForm):
    start_time = forms.DateField(widget=widgets.AdminTimeWidget)
    end_time = forms.DateField(widget=widgets.AdminTimeWidget)
    create_date = forms.DateField(widget=widgets.AdminDateWidget)
    class Meta:
        model=Guide
        fields=['name','categorie','thumb']
作者: potemkin 发布者: 21.07.2018 07:26

2

9897 作者的声誉

对于Django> = 2.0

注意:对于日期时间字段使用admin小部件不是一个好主意,因为如果您使用引导程序或任何其他CSS框架,管理样式表可能与您的站点样式表冲突。如果您在bootstrap上构建站点,请使用我的bootstrap-datepicker小部件django-bootstrap-datepicker-plus

第1步:javascript-catalogURL 添加到项目的(不是应用程序)urls.py文件中。

from django.views.i18n import JavaScriptCatalog

urlpatterns = [
    path('jsi18n', JavaScriptCatalog.as_view(), name='javascript-catalog'),
]

第2步:向模板添加所需的JavaScript / CSS资源。

<script type="text/javascript" src="{% url 'javascript-catalog' %}"></script>
<script type="text/javascript" src="{% static '/admin/js/core.js' %}"></script>
<link rel="stylesheet" type="text/css" href="{% static '/admin/css/widgets.css' %}">
<style>.calendar>table>caption{caption-side:unset}</style><!--caption fix for bootstrap4-->
{{ form.media }}        {# Form required JS and CSS #}

第3步:使用管理窗口小部件来显示您的日期时间输入字段forms.py

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

class ProductCreateForm(forms.ModelForm):
    class Meta:
        model = Product
        fields = ['name', 'publish_date', 'publish_time', 'publish_datetime']
        widgets = {
            'publish_date': widgets.AdminDateWidget,
            'publish_time': widgets.AdminTimeWidget,
            'publish_datetime': widgets.AdminSplitDateTime,
        }
作者: Munim Munna 发布者: 17.08.2018 10:36

0

1496 作者的声誉

我的Django设置:1.11 Bootstrap:3.3.7

由于没有一个答案是完全清楚的,我正在分享我的模板代码,它根本不会出现任何错误。

模板的上半部分:

{% extends 'base.html' %}
{% load static %}
{% load i18n %}

{% block head %}
    <title>Add Interview</title>
{% endblock %}

{% block content %}

<script type="text/javascript" src="{% url 'javascript-catalog' %}"></script>
<script type="text/javascript" src="{% static 'admin/js/core.js' %}"></script>
<link rel="stylesheet" type="text/css" href="{% static 'admin/css/forms.css' %}"/>
<link rel="stylesheet" type="text/css" href="{% static 'admin/css/widgets.css' %}"/>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" >
<script type="text/javascript" src="{% static 'js/jquery.js' %}"></script>

下半区:

<script type="text/javascript" src="/admin/jsi18n/"></script>
<script type="text/javascript" src="{% static 'admin/js/vendor/jquery/jquery.min.js' %}"></script>
<script type="text/javascript" src="{% static 'admin/js/jquery.init.js' %}"></script>
<script type="text/javascript" src="{% static 'admin/js/actions.min.js' %}"></script>
{% endblock %}
作者: Arindam Roychowdhury 发布者: 11.03.2019 10:22
32x32
{{ f.name }} {{ f }}