【问题标题】:UpdateView with form_class removes named submit input from POST带有 form_class 的 UpdateView 从 POST 中删除命名提交输入
【发布时间】:2021-04-12 11:51:34
【问题描述】:

我想知道用户点击了哪个提交输入。提交的表单转到使用ModelFormUpdateView。我已将名称属性添加到提交输入,但是当我在 get_context_data() 中执行 if 'approve' in self.request.POST: 时,它是 False。我覆盖了def post()approvePOST 字典中的一个键。有没有办法让approvedecline 显示在get_context_data() 中?。

猜测它必须与所涉及的 ModelForm 有关,但有没有办法在不覆盖 post 方法的情况下通过它,或者我应该只是将它排除在外?

仅供参考,我省略了一些臃肿且与问题无关的代码。如有不妥之处,请见谅。

models.py

class Definition(DefinitionInfo):
    SEV3 = 'info'
    SEV2 = 'warning'
    SEV1 = 'danger'
    sup_sevs = (
        ('', 'Please select'),
        (SEV3, 'Sev3'),
        (SEV2, 'Sev2'),
        (SEV1, 'Sev1'),
    )
    title = models.CharField(max_length=255)
    description = models.TextField(null=True, blank=True)
    resolution = models.TextField(null=True, blank=True)
    sup_sev = models.CharField(max_length=7, choices=sup_sevs, null=False, blank=False)

forms.py

class DefinitionForm(forms.ModelForm):
    class Meta:
        model = Definition
        fields = ['title', 'sup_sev', 'description', 'resolution']
        widgets = {
            'description': forms.HiddenInput(),
            'resolution': forms.HiddenInput(),
        }

views.py

class DefinitionUpdate(LoginRequiredMixin, UpdateView):
    model = Definition
    context_object_name = 'definition'
    form_class = DefinitionForm
    template_name_suffix = '_form'
    success_url = reverse_lazy('definitions:index')

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        if self.request.method == 'POST':
            print(f'Post data: {self.request.POST}')
        return context

update_form.html

<form id="defForm" class="container-sm w-50" enctype="multipart/form-data" method="post" action=".">
  {% csrf_token %} {{ form.delete }}
  <div class="row g-3">
    <div class="col-md-10">
      <div class="form-floating mb-3">
        <input type="text" class="form-control form-control-sm bg-dark text-light" id="{{ form.title.auto_id }}" name="{{ form.title.html_name }}" placeholder="Enter title here..." value="{{ form.title.value|default_if_none:'' }}">
        <label class="form-label" for="{{ form.title.id_for_label }}">Title</label>
      </div>
    </div>
    <div class="col-sm">
      <div class="form-floating mb-3">
        {{ form.sup_sev }}
        <label class="form-label" for="{{ form.sup_sev.id_for_label }}">Severity</label>
      </div>
    </div>
  </div>
  <div class="form-floating mb-3">
    {{ form.description }}
    <div id="description" class="form-control form-control-sm bg-dark text-light d-inline-block" style="white-space: pre-wrap;" contentEditable>{{ form.description.value|default_if_none:'' }}</div>
    <label class="form-label" for="{{ form.description.id_for_label }}">Description</label>
  </div>
  <div class="form-floating mb-3">
    {{ form.resolution }}
    <div id="resolution" class="form-control form-control-sm bg-dark text-light d-inline-block" style="white-space: pre-wrap;" contentEditable>{{ form.resolution.value|default_if_none:'' }}</div>
    <label class="form-label" for="resolution">Resolution</label>
  </div>
  <div class="d-grid gap-2 d-md-flex justify-content-md-end">
    <input id="decline" class="btn btn-outline-danger" name="decline" type="submit" value="Decline">
    <input id="approve" class="btn btn-outline-success" name="approve" type="submit" value="Approve">
  </div>
</form>

【问题讨论】:

  • approve 只有在用户单击“保存”按钮时才会出现在输入数据中。如果他们单击拒绝按钮,则不会。是这个问题吗?
  • 不,抱歉。所以我只想知道用户点击了哪个提交输入。只需要在self.request.POST 中存在批准或拒绝的密钥。目前get_context_data() 中的任何一个被点击时都不会发生这种情况。只有当我覆盖 post() 时,我才能在 POST 字典中看到批准或拒绝。

标签: python django forms post form-submit


【解决方案1】:

所以经过一段时间后,我已经解决了。

首先我发现我有一个使用$(this).submit(); 提交表单的Jquery 脚本。当然,这意味着提交它的不是提交输入。因此,只需删除它并 preventDefault(); 它就可以了。下面是罪魁祸首。它将文本复制到相对隐藏的输入中。 (所以我有一个自动调整大小但仍将信息发送到服务器的文本区域)

$(document).ready(function() {
    let form = $('#defForm')
    let descDiv = $("#description");
    let resoDiv = $('#resolution');
    form.one('submit', function(e) {
        // e.preventDefault();
        let descTa = $("#id_description");
        let resoTa = $("#id_resolution");
        descTa.val(descDiv.text());
        resoTa.val(resoDiv.text());
        //$(this).submit();
    });
});

第二个原因是我需要在表单中进行一些额外的配置。

我在ModelForm 中添加了两个字段,分别称为approvedecline。每个都是CharField,不是必需的,并且包括一个TextInput 小部件,其中attrs 具有{'type': 'submit', 'value': 'Approve'}(不完全需要,但如果您只在模板中使用{{ form.approve }} 则很好)。

这样做不仅可以在get_context_data() 内显示self.request.POST 中的点击提交,还可以显示更有用的form_valid()

class DefinitionForm(forms.ModelForm):
    approve = forms.CharField(widget=forms.TextInput(attrs={'type': 'submit', 'value': 'Approve'}), required=False)
    decline = forms.CharField(widget=forms.TextInput(attrs={'type': 'submit', 'value': 'Decline'}), required=False)
    
    class Meta:
        model = Definition
        fields = ['title', 'sup_sev', 'description', 'resolution']
        widgets = {
            'description': forms.HiddenInput(),
            'resolution': forms.HiddenInput(),
        }

【讨论】:

    猜你喜欢
    • 2013-07-14
    • 1970-01-01
    • 2018-11-13
    • 2011-12-12
    • 2012-07-19
    • 1970-01-01
    • 1970-01-01
    • 2017-09-07
    • 1970-01-01
    相关资源
    最近更新 更多