0

所以我目前正在 Django 中进行该项目。用户应该能够设置开始日期和结束日期,基于这个设置的间隔应该计算分析。

当前的问题是,当数据进行验证时,它将输入数据视为 NoneType。

注意:我没有上传整个 html 代码。仅形成相关代码。

表格.py

from django import forms
from tempus_dominus.widgets import DatePicker
import datetime


class AnalysisInformationForm(forms.Form):
    start = forms.DateField(help_text="Enter a date between 2019-03-01 and now.",
                            input_formats=["%d/%m/%Y"],
                            widget=DatePicker(
                                options={
                                    'minDate': '2019-03-01',
                                    'maxDate': datetime.datetime.utcnow().date().strftime("%Y-%m-%d")
                                })
                            )
    end = forms.DateField(help_text="Enter a date between the chosen start date and now",
                          input_formats=["%d/%m/%Y"],
                          widget=DatePicker(
                              options={
                                  'minDate': '2019-03-01',
                                  'maxDate': datetime.datetime.utcnow().date().strftime("%Y-%m-%d")
                              })
                          )

    def clean(self):
        cleaned_data = super(AnalysisInformationForm, self).clean()
        start = cleaned_data.get('start')
        end = cleaned_data.get('end')
        print(start, end)
        if start >= end:
            raise forms.ValidationError('Invalid dates input. The start day must be set earlier than the end date. ')
        return cleaned_data

视图.py

def index(request):
    if request.method == 'POST':
        form = AnalysisInformationForm(request.POST)
        if form.is_valid():
            pass
    else:
        form = AnalysisInformationForm()
    return render(request, 'stm/index.html', {'form': form})

索引.html

<head>
        <link rel="stylesheet" href="https://netdna.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.css">
        <link rel="stylesheet" href="{%  static 'css/bootstrap.css' %}"><link>
        <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
</head>
        {{ form.media }}
<body>
<div class="form-group"></div>
                        {% load widget_tweaks %}
                        <form method="post" novalidate>
                            {% csrf_token %}

                            {% for hidden_field in form.hidden_fields %}
                                {{ hidden_field }}
                            {% endfor %}

                            {% if form.non_field_errors %}
                                <div class="alert alert-danger" role="alert">
                                  {% for error in form.non_field_errors %}
                                    {{ error }}
                                  {% endfor %}
                                </div>
                            {% endif %}

                            {% for field in form.visible_fields %}
                                <div class="input-group">
                                {{ field.label_tag }}
                                {% if form.is_bound %}
                                    {% if field.errors %}
                                        {% render_field field class="form-control is-invalid" %}
                                        {% for error in field.errors %}
                                            <div class="invalid-feedback">
                                              {{ error }}
                                            </div>
                                        {% endfor %}
                                    {% else %}
                                        {% render_field field class="form-control is-valid" %}
                                    {% endif %}
                                {% else %}
                                    {% render_field field class="form-control" %}
                                {% endif %}
                                {% if field.help_text %}
                                    <small class="form-text text-muted">{{ field.help_text }}</small>
                                {% endif %}
                                </div>
                            {% endfor %}
                            <div class="input-group m-3">
                                <input type="submit" class="btn btn-outline-secondary btn-block" value="Continue">
                            </div>
                        </form>
</body>

这些教程将我带到了这个解决方案:

https://simpleisbetterthancomplex.com/article/2017/08/19/how-to-render-django-form-manually.html#rendering-bootstrap-4-forms

https://pypi.org/project/django-tempus-dominus/

https://pypi.org/project/django-widget-tweaks/

我还发现了一个关于堆栈溢出的类似问题,但没有答案: Django DateField form generate None incleaned_data

我还尝试执行以下操作来检查实际数据是否通过。所以在views.py中我改变了以下内容:之前:

form = AnalysisInformationForm(request.POST)

后:

form = request.POST['start']
print(form)

在错误之间,我发现了该打印语句。令人惊讶的是,给定的开始日期确实与实际输入相匹配。但是在数据被清理之后,它变成了一个 NoneType 值。

任何建议可能是什么原因?

预期结果是数据能够得到验证,如代码所示。开始日期必须设置得早于结束日期,否则显示错误消息。

4

4 回答 4

1

所以在尝试了几件事之后。我找到了以下解决方案:首先在 forms.py 中,我更新了 clean 函数以匹配以下内容。在stackoverflow的某处找到了这个干净的函数,但忘记保存它的链接,不知道这是否可行:

    def clean(self):
        data = self.cleaned_data
        print(data)
        start = data.get('start')
        end = data.get('end')
        if start >= end:
            raise forms.ValidationError('Invalid dates input. The start day must be set earlier than the end date. ')
        return data

然后我尝试了几种日期输入格式,比如["%y/%m/%d"](19/04/02格式,不是iso)、["%Y/%m/%d"](2019/04 /02 格式,非 iso), ["%y-%m-%d"](19-04-02 格式, 非 iso), ["%Y-%m-%dT%H:%M:%S .%fZ"](好吧,iso 日期时间格式,但我使用的是日期对象而不是日期时间对象)。所以我得出的结论是,我只需将 ["%Y/%m/%d"] 中的 / 更改为 - ,一切都应该正常工作。它确实有效:D

这是新更新的表单类的样子:

class AnalysisInformationForm(forms.Form):
    start = forms.DateField(help_text="Enter a date between 2019-03-01 and now.",
                            input_formats=["%Y-%m-%d"],
                            widget=DatePicker(
                                options={
                                    'minDate': '2019-03-01',
                                    'maxDate': datetime.datetime.utcnow().date().strftime("%Y-%m-%d")
                                })
                            )
    end = forms.DateField(help_text="Enter a date between the chosen start date and now",
                          input_formats=["%Y-%m-%d"],
                          widget=DatePicker(
                              options={
                                  'minDate': '2019-03-01',
                                  'maxDate': datetime.datetime.utcnow().date().strftime("%Y-%m-%d")
                              })
                          )

感谢所有试图提供帮助的人,您帮助我找到了正确的解决方案。

于 2019-04-02T07:41:24.507 回答
0

可能您需要在 html 中将“post”全部大写

 <form method="POST" novalidate>
于 2019-04-01T13:30:42.243 回答
0

对于 django 2.1 试试这个

def clean(self):
    cleaned_data = super().clean()
    start = cleaned_data.get("start")
    end = cleaned_data.get("end")

希望能帮助到你

于 2019-04-01T13:37:58.713 回答
0

尝试在调用 super() 之前查找传递给 clean() 方法的内容。也许它来自非iso格式的客户端,并且没有通过超类的默认验证

于 2019-04-01T13:39:52.517 回答