【问题标题】:Data not saving in Model数据未保存在模型中
【发布时间】:2021-02-22 21:49:55
【问题描述】:

我已经为我拥有的模型制作了模型表单,我无法直接将数据保存到模型,因为我有一个自定义格式日期字段,只能在 forms.py 中使用forms.DateField(input_formats=settings.DATE_INPUT_FORMATS) 制作,但由于某种原因数据我正在解析视图并没有保存在模型中。

views.py

def applications_view(request):
    if request.user.is_superuser:
        applications = LeaveApplication.objects.all()
        if request.method == "POST":
            id = request.POST.get('applications_id')
            user = request.POST.get('applications_user')
            reason = request.POST.get('applications_reason')
            from_date = request.POST.get('applications_from_date')
            to_date = request.POST.get('applications_to_date')
            if request.POST.get('approve'):
                something = LeaveList(user=user, reason=reason, from_date=from_date,
                 to_date=to_date, leave_status='Approve')
                leave_list_form = LeaveListForm(request.POST, instance=something)
                if leave_list_form.is_valid():
                    leave_list_form.save()             
            elif request.POST.get('deny'):
                something = LeaveList(user=user, reason=reason, from_date=from_date,
                 to_date=to_date, leave_status='Denied')
                leave_list_form = LeaveListForm(request.POST, instance=something)
                if leave_list_form.is_valid():
                    leave_list_form.save()          
        context = {
            'applications': applications
        }
        return render(request, 'home/applications.html', context)

forms.py

class LeaveListForm(forms.ModelForm):
    from_date = forms.DateField(input_formats=settings.DATE_INPUT_FORMATS)
    to_date = forms.DateField(input_formats=settings.DATE_INPUT_FORMATS)
    class Meta:
        model = LeaveList
        fields = [
            'user',
            'reason',
            'from_date',
            'to_date',
            'leave_status'
        ]

我没有在模板上呈现带有上下文的表单,因为我正在循环来自另一个模型的数据,我在每个循环都呈现的隐藏类型输入的帮助下使用按钮再次获取这些数据。

<table style="width:100%">
                <tr>
                    <th>Request ID</th>
                    <th>Employee</th>
                    <th>Reason for Leave</th>
                    <th>From Date</th>
                    <th>To Date</th>
                    <th>Approve/Deny</th>
                </tr>
                <tr>
                    <td>{{ applications.id }}</td>
                    <td>{{ applications.user }}</td>
                    <td>{{ applications.reason }}</td>
                    <td>{{ applications.from_date }}</td>
                    <td>{{ applications.to_date }}</td>
                    <td>
                    <form method="POST">
                    {% csrf_token %}
                    <input type="hidden" id="applications_id" name="applications_id" value="{{ applications.id }}">
                    <input type="hidden" id="applications_user" name="applications_user" value="{{ applications.user }}">
                    <input type="hidden" id="applications_reason" name="applications_reason" value="{{ applications.reason }}">
                    <input type="hidden" id="applications_from_date" name="applications_from_date" value="{{ applications.from_date }}">
                    <input type="hidden" id="applications_to_date" name="applications_to_date" value="{{ applications.to_date }}">
                    <input class="appproveButton appproveButtonYes" type="submit" name="approve" value="Approve">
                    <input type="submit" class="appproveButton appproveButtonNo"name="deny" value="Deny">
                    </form>
                    </td>
                </tr>
            </table>

【问题讨论】:

  • settings.DATE_INPUT_FORMATS 的格式是什么,你在 request.POST.get('applications_from_date') 中传递了什么?
  • @KasimSharif DATE_INPUT_FORMATS = ['%b. %d, %Y'],对于 'applications_from_date' 是 2021 年 2 月 24 日(示例)
  • 为什么在保存之前leave_list_form = LeaveListForm(request.POST, instance=something) 这样做。此外,您的验证似乎很可能失败,这意味着您的 save() 永远不会被调用。您是否检查过表单是否通过验证?
  • 我认为leave_list_form = LeaveListForm(request.POST, instance=something) 会将数据保存在字段中。我之前遇到了验证错误,但在添加 if leave_list_form.is_valid(): 之后就没有了,所以我认为表单正在通过验证。
  • 没有。那不会保存数据。 something.save() 会在验证通过时。将else: 添加到您的if form.isvalid() 并查看它是否通过。似乎不是。

标签: python django django-models django-views


【解决方案1】:

既然您已经在使用您的表单,为什么还要处理获取数据?只需将 POST 数据传递给表单并让它处理它。此外,您似乎不想从表单中获取 leave_status 而是在表单中传递一个不同的键,如果是这种情况,只需将它们从表单中删除并自己处理:

from django.shortcuts import redirect


def applications_view(request):
    if request.user.is_superuser:
        applications = LeaveApplication.objects.all()
        if request.method == "POST":
            form = LeaveListForm(request.POST)
            if form.is_valid():
                if request.POST.get('approve'):
                    leave_status = 'Approve'
                elif request.POST.get('deny'):
                    leave_status = 'Denied'
                else:
                    leave_status = 'SOME_DEFAULT_VALUE'
                form.instance.leave_status = leave_status
                form.save()
                return redirect('<SOME_URL_NAME>') # Redirect after successful form save!
        context = {
            'applications': applications,
        }
        return render(request, 'home/applications.html', context)

现在因为您使用不同的视图来呈现表单:

def other_view(request, *args, **kwargs):
    form = LeaveListForm()
    # rest of view
    context = {..., 'form': LeaveListForm()}
    return render(request, 'some_template.html', context)

在您的表单中:

class LeaveListForm(forms.ModelForm):
    from_date = forms.DateField(input_formats=settings.DATE_INPUT_FORMATS) # Make sure the input formats are correct
    to_date = forms.DateField(input_formats=settings.DATE_INPUT_FORMATS)
    class Meta:
        model = LeaveList
        fields = [
            'user',
            'reason',
            'from_date',
            'to_date',
        ] # Removed leave_status from here

另外,您似乎是通过编写 html 自己直接渲染表单。即使您想这样做,您也需要牢记表单并将输入的名称设置为表单所期望的名称!要么简单地将表单渲染留给 django,要么更正您的输入标签名称。我建议将表单渲染留给 django:

<form method="post">
    {% csrf_token %}
    {{ form.as_p }}
    <input type="submit" name="approve" value="Approve">
    <input type="submit" name="deny" value="Deny">
</form>

如果您不喜欢 Django 呈现表单的方式并希望对其进行自定义,那么有很多很棒的包可以帮助您做到这一点,例如django-widget-tweaksdjango-crispy-forms

【讨论】:

  • 谢谢,但我使用名称标签获取数据的原因是因为我没有在模板上呈现带有上下文的表单。您能否帮助我了解如何将这些获取的数据保存到表单中?
  • @udaykls 我已经编辑了答案做检查。您可以简单地在另一个视图中传递表单并在那里呈现表单。无论如何,表单是一个单独的实例,并从此处的发布数据进行验证。如果您想自定义表单的外观,请检查我在答案中推荐的包,或者您也可以通过制作自定义模板并将一些参数传递给表单类中的字段来自己进行一些修改。
  • @udaykls 如果您坚持手动渲染表单,那么仍然使用 Django 自动渲染表单并检查您需要为每个输入设置的名称属性,然后对应于写入表单输入.
  • 关于渲染表单,我已经编辑了我的问题。所以我用for循环在模板上显示数据,我需要在按钮的帮助下获取循环数据,所以我在每个循环中使用隐藏类型的输入,并分别显示数据,所有这些都完美无缺,所以我什至无法渲染数据如果我想,除非我想改变价值。对于自动渲染一次并将名称设置为表单输入,我仍然需要手动将数据保存到模型表单,对吗?如果我没有正确理解您,请告诉我。
  • @udaykls 现在这是一个XY problem,如果你能告诉我们你想做什么,你就不会浪费这么多时间了......基本上你1)已经有另一个实例模型。 2)似乎您只想复制此模型的数据并将其保存为接受或拒绝。我想说的是为什么还要发布所有模型数据?您可以简单地发送该模型的 id 并在您的视图中获取实例...
猜你喜欢
  • 1970-01-01
  • 2015-11-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-11
  • 1970-01-01
  • 2023-03-28
  • 1970-01-01
相关资源
最近更新 更多