【问题标题】:Django refuses to save the date shown on formDjango 拒绝保存表单上显示的日期
【发布时间】:2013-05-16 03:54:00
【问题描述】:

我有一个表单,允许用户编辑他们的个人资料。其中一个字段是“出生日期”。在编辑时,表单会从数据库 (mySQL) 中获取日期,并以“1982 年 6 月 10 日”的格式显示。当我点击“提交”时,它会抛出错误:“输入有效日期。”该字段是“只读”的,因此使用 datepicker 选择日期。我正在使用来自 eternicode (https://github.com/eternicode/bootstrap-datepicker/) 的日期选择器

为了呈现表单,我使用了crispy-forms (v1.2.3) 和 twitter-bootstrap。

使用日期选择器选择日期时,其格式为 mm/dd/yyyy。提交表单时会正确保存。

我在 SO 或其他地方找不到任何可以解决我的问题的东西。我觉得这应该是某个地方的小调整,但尽管有很多不同的方法,但仍无法确定它。

顺便说一句,如果我在'input'标签中指定value="{{ field.value|date:'m/d/Y' }}",它会以这种格式显示日期并成功保存,但随后从小部件中消失,直到重新加载表单(可以通过刷新页面重新加载)

在 settings.py 中:USE_I18N、USE_L10N 和 USE_TZ 都设置为 'True',TIME_ZONE = 'Asia/Kolkata'

如果可能,我希望将显示日期保持为“1982 年 6 月 10 日”格式,并且仍然能够保存表单。否则,我不介意更改表单小部件中的显示日期格式。非常感谢您的帮助。

这是我的相关代码 sn-ps:
models.py

class Profile(models.Model):

    class Meta:
        verbose_name_plural = _('Profiles')

    user = models.OneToOneField(User, verbose_name=_('User'), related_name='enduser',     unique=True)
    dob = models.DateField(_('Date of Birth'), help_text=_(u"Age: 18yrs - 90yrs"))
    :
    :  

forms.py

class ExtendedProfileForm(forms.ModelForm):

class Meta:
    model = Profile
    exclude = ('user',)

# some crispy forms related code
def __init__(self, *args, **kwargs):

    super(ExtendedProfileForm, self).__init__(*args, **kwargs)

    self.helper = FormHelper()
    self.helper.form_class = 'form-inline'
    self.helper.form_tag = False
    self.helper.html5_required = True
    self.helper.help_text_inline = True
    self.helper.attrs = {'accept-charset' : 'utf-8'}

    fieldlist = self.fields.keys()
    newlist = []
    for key in fieldlist:
        if key == 'dob':
            newlist.append(Field("dob", css_class="input-small", readonly="readonly", id="id_dob", template="datepick.html", input_formats=(settings.DATE_INPUT_FORMATS)))
        else:
            newlist.append(key)

    self.helper.layout = Layout(
        Fieldset("",
                 *newlist
        ),
    )  

datepick.html

{% comment %}
  Ref: https://github.com/maraujop/django-crispy-forms/issues/134
{% endcomment %}
{% load crispy_forms_field %}
<div id="div_{{ field.auto_id }}" class="clearfix control-group{% if field.errors %}     error{% endif %}">
    {% if field.label %}
        <label for="id_{{ field.id_for_label }}" class="control-label {% if   field.field.required %}requiredField{% endif %}"> {{ field.label|safe }}{% if field.field.required %}<span class="asteriskField">*</span>{% endif %} </label>
    {% endif %}
    <div class="controls">
        <div id="{{ field.auto_id }}" class="input-append date" data-date-format="%m/%d/%Y">
            <input size="40" type="text" readonly="readonly" {% if field.value %} value="{{ field.value }}"{% endif %} name="{% if form.prefix %}{{form.prefix}}-{% endif %}{{ field.name }}"/><span class="add-on"><i class="icon-calendar">&nbsp;</i></span>
        </div>
        {% include 'bootstrap/layout/help_text_and_errors.html' %}
    </div>
</div>

settings.py

DATE_INPUT_FORMATS = (
    '%Y-%m-%d', '%m/%d/%Y', '%m/%d/%y', # '2006-10-25', '10/25/2006', '10/25/06'
    '%b %d %Y', '%b %d, %Y',            # 'Oct 25 2006', 'Oct 25, 2006'
    '%d %b %Y', '%d %b, %Y',            # '25 Oct 2006', '25 Oct, 2006'
    '%B %d %Y', '%B %d, %Y',            # 'October 25 2006', 'October 25, 2006'
    '%d %B %Y', '%d %B, %Y',            # '25 October 2006', '25 October, 2006'
)  

对 datepicker 的 JS 调用

    $('#id_dob').datepicker({
        format : 'mm/dd/yyyy',
        endDate : '-18y', // 18 years in the past
        startDate : '-90y', // we assume a person to be max 90 years old to use this site
        startView : 2,
        autoclose : true,
    }); 

【问题讨论】:

  • 试试这个dob = forms.DateField(initial=date.today(), widget=forms.DateInput(format = '%d.%m.%Y'), input_formats=('%d.%m.%Y',))根据你的需要改变日期格式

标签: django twitter-bootstrap django-crispy-forms datepicker


【解决方案1】:

您需要在表单字段上定义类似于 datepicker 格式的日期格式:

def ExtendedProfileModel(forms.ModelForm):
    dob = forms.DateField(label=_('Date of birth'), input_formats=['%m/%d/%y'])

    def __init__(self, *args, **kwargs):
        super(ExtendedProfileModel, self).__init__(*args, **kwargs)
        self.fields['dob'].widget.format = '%m/%d/%y'

【讨论】:

  • 通过在表单上添加自定义字段来尝试。查看更新的答案并确保 datepicker 的格式为 mm/dd/yyyy
  • 嗨,阿米尔,首先,非常感谢您的回答。不幸的是,这两种方法都不起作用。
  • 没问题。这应该有效。您对日期字段是否有任何自定义验证可能会引发错误?你能显示你从哪一天过去吗?
【解决方案2】:

感谢 Aamir Adnan 和 kartheek,他们给了我正确的指导!

最终奏效的是在 ExtendedProfileForm 的 init 中添加以下内容

        self.fields['dob'].input_formats=(settings.DATE_INPUT_FORMATS)  

所以现在我的表格是这样的,它工作得很好!

class ExtendedProfileForm(forms.ModelForm):

class Meta:
    model = Profile
    exclude = ('user',)

# some crispy forms related code
def __init__(self, *args, **kwargs):

    super(ExtendedProfileForm, self).__init__(*args, **kwargs)

    self.helper = FormHelper()
    self.helper.form_class = 'form-inline'
    self.helper.form_tag = False
    self.helper.html5_required = True
    self.helper.help_text_inline = True
    self.helper.attrs = {'accept-charset' : 'utf-8'}
    self.fields['dob'].input_formats=(settings.DATE_INPUT_FORMATS)

    fieldlist = self.fields.keys()
    newlist = []
    for key in fieldlist:
        if key == 'dob':
            newlist.append(Field("dob", css_class="input-small", readonly="readonly", id="id_dob", template="datepick.html"))
        else:
            newlist.append(key)

    self.helper.layout = Layout(
        Fieldset("",
                 *newlist
        ),
    )

【讨论】:

  • Sandeep,感谢您详细回答。它对我帮助很大。
猜你喜欢
  • 2015-05-24
  • 1970-01-01
  • 1970-01-01
  • 2019-03-02
  • 1970-01-01
  • 2013-03-27
  • 2014-05-31
  • 1970-01-01
  • 2013-12-07
相关资源
最近更新 更多