如何在django的ModelForm中使用DatePicker?

fcwjkofz  于 2023-03-24  发布在  Go
关注(0)|答案(4)|浏览(114)

我正在使用django 3.0,我试图在我的ModelForm中显示一个datepicker小部件,但我不知道怎么做(我能得到的只是文本字段)。我试图寻找一些解决方案,但找不到任何解决方案。这是我的模型和我的ModelForm的样子:

class Membership(models.Model):
  start_date = models.DateField(default=datetime.today, null=True)
  owner = models.ForeignKey(Client, on_delete=models.CASCADE, null=True)
  type = models.ForeignKey(MembershipType, on_delete=models.CASCADE, null=True)

class MembershipForm(ModelForm):
  class Meta:
    model = Membership
    fields = ['owner', 'start_date', 'type']
    widgets = {
        'start_date': forms.DateInput
    }

这是我的HTML:

<form class="container" action="" method="POST">
{% csrf_token %}
{{ form|crispy }}
<button type="submit" class="btn btn-primary">Submit</button>
</form>
u4dcyp6a

u4dcyp6a1#

尽管@willem-van-onsem的答案很好,但也有一些不需要额外依赖项的替代方法。
以下是几个选项,按努力程度的顺序排列:
1.使用SelectDateWidget而不是默认的DateInput(* 不需要 * JavaScript):

class MyForm(forms.Form):
    date = forms.DateField(widget=forms.SelectDateWidget())

1.使用浏览器的内置日期选择器,通过实现一个使用HTML 元素的自定义小部件(* 不需要 * JavaScript):

class MyDateInput(forms.widgets.DateInput):
    input_type = 'date'

class MyForm(forms.Form):
    date = forms.DateField(widget=MyDateInput())

或者:

class MyForm(forms.Form):
    date = forms.DateField(widget=forms.DateInput(attrs=dict(type='date')))

1.使用django.contrib.admin中的日期选择器,如here中详细描述的。简而言之,您需要以下几件事:

from django.contrib.admin.widgets import AdminDateWidget
...
class MyForm(forms.Form):
    date = forms.DateField(widget=AdminDateWidget())

然后,为了使其工作,将以下依赖项添加到模板<head>

<link rel="stylesheet" type="text/css" href="{% static 'admin/css/widgets.css' %}" />
<script src="{% static 'admin/js/core.js' %}"></script>
<script src="{% url 'admin:jsi18n' %}"></script>  {# see note below #}
{{ form.media }}  {# this adds 'calendar.js' and 'DateTimeShortcuts.js' #}

现在有一个问题:admin:jsi18n url仅适用于具有管理员访问权限的用户,因此您可能需要替换此URL并在urls.py中定义替代路径,例如:

from django.views import i18n
...
urlpatterns = [
    ...,
    path('jsi18n/', i18n.JavaScriptCatalog.as_view(), name='jsi18n'),
]

最后,下面是小部件的样子(在Firefox上):

我个人最喜欢第二个选项。它还允许我们指定初始值,最小值和最大值(在django中,你可以使用attrs参数来实现这一点)。这里有一个快速的片段来展示HTML元素的作用:

<input type="date" value="2021-09-09" min="2021-09-09">
vql8enpb

vql8enpb2#

Django 4.0。把它留在这里,以防对其他人有帮助。这将设置最小日期和默认值为今天的日期,应该在forms.py中使用。在我的例子中,我在我的.html中使用脆的表单来呈现字段。

from datetime import date

today = date.today()
    
class DateForm(forms.ModelForm):
   target_Date = forms.DateField(widget=forms.TextInput(attrs={'min': today, 'value': today, 'type': 'date'}), required=True)

class Meta:
    model = DateForm
    fields = ['target_Date']
c8ib6hqw

c8ib6hqw3#

这是预期的行为。**DateInput**widget [Django-doc]只是一个带有可选format参数的<input type="text">元素。
您可以使用一个包,例如django-bootstrap-datepicker-plus [pypi],然后使用DatePickerInput定义一个表单:

from bootstrap_datepicker_plus import DatePickerInput

class MembershipForm(ModelForm):
  class Meta:
    model = Membership
    fields = ['owner', 'start_date', 'type']
    widgets = {
        'start_date': DatePickerInput
    }

在模板中,您需要呈现表单的媒体并加载 Bootstrap css和javascript:

{% load bootstrap4 %}
{% bootstrap_css %}
{% bootstrap_javascript jquery='full' %}
{{ form.media }}

<form class="container" action="" method="POST">
{% csrf_token %}
{{ form|crispy }}
<button type="submit" class="btn btn-primary">Submit</button>
</form>
iszxjhcz

iszxjhcz4#

正如其他人所说,这是预期的,因为它只是一个特殊的文本字段。
我更喜欢使用django-widget-tweaks,因为这会将前端定制推回模板,而不是在后端编辑forms.py。保存/测试也更快,因为应用程序不必在每次保存时重新加载。
安装到您的环境:

pip install django-widget-tweaks

添加到已安装的应用:

INSTALLED_APPS = [
   ...
   "widget_tweaks",
]

添加到您的模板:

{% extends 'app/base.html' %}
{% load widget_tweaks %}

使用带有input标签属性的render_field来定制你的字段。例如下面使用bootstrap 5。注意我们如何在模板标签中指定属性,如typeclass

<div class="col-2">
   <label for="{{ form.date.id_for_label }}" class="col-form-label">{{ form.year.label }}</label>
</div>
<div class="col-4">
   {% render_field form.year type="date" class="form-control" placeholder="mm/dd/yyyy" %}
<div>

相关问题