【问题标题】:Why is my Django form returning the QueryDict without the submitted data?为什么我的 Django 表单在没有提交数据的情况下返回 QueryDict?
【发布时间】:2020-09-27 18:00:57
【问题描述】:

我遇到的问题是我的表单数据返回不是无,也不是我输入的表单值,而只是通常的 csrf_token 字符串和按钮的值。

我通过打印 Form(response.POST).data 验证了这一点,它返回一个仅包含 csrf_token 值和提交按钮值的 QueryDict:

<QueryDict: {'csrfmiddlewaretoken': ['the token string'], 'save_customer': ['save_customer']}>

将此与其他工作表单的有效输出进行对比。 (我碰巧执行这两个过程几乎相同):

<QueryDict: {'tail': ['aasdf'], 'aircraft': ['asdf'], ...it's all here... 'csrfmiddlewaretoken': ['the token string'], 'add': ['add']}>

所以基本上,我的 HTML 文件包含 2 个表单。一种形式有效,另一种无效。拥有多个表单应该不是问题,尤其是考虑到一个表单位于其自己的单独容器中,而另一个表单位于模式中。他们之间不共享任何“div”,也不共享任何“养育”。

但是,应该注意的是,第二个表单的相应视图会在页面加载时自动执行,而无需事先进行任何操作。第二种形式的简单存在导致了这种情况的发生。我已经删除了 javascript 文件,删除了第二种形式中的所有 javascript 功能痕迹,但视图仍然被自动调用。虽然这似乎是一个单独的问题,但我承认我经验不足,无法有效地确定这里的因果关系。

这是我的视图、模型和 HTML 文件的样子:

view.py

def add(response):

    if response.method == "POST":
        form = Form(response.POST)
        # some other forms that works ...
        elif response.POST.get("save_customer"):
            # How is this getting called automatically on each page load anyway?
            if form.is_valid():
                customer = process_new_customer(form)
                customer.save()

    return render("executing this part works fine")

def process_new_customer(form):

    tail_number = form.data.get('tail')  # Doesn't exist
    first_name = form.data.get('first_name')  # Doesn't exist
    last_name = form.data.get('last_name')  # Doesn't exist

    customer = Customer(
        tail_number=tail_number,
        first_name=first_name,
        last_name=last_name,
    )

    return customer  # This is None

models.py

class Customer(models.Model):


    tail_number = models.CharField(max_length=45, primary_key=True, null=False, blank=False)
    first_name = models.CharField(max_length=45, null=True, blank=True)  # Not exactly required
    last_name = models.CharField(max_length=45, null=True, blank=True)  # but recommended

    customers = models.Manager()

    def __str__(self):
        return str(self.tail_number)

HTML: (这个有点长,我觉得问题可能出在这里的某个地方)

<form method="post" class="form_group border border-dark">
    {% csrf_token %}
    <!-- A separate form in the same file that works -->
</form>


<!-- The 'submit' portion is at the bottom, not sure to what extent these other detail are relevant -->
<form id="saveCustomerInfoForm" method="POST" class="form_group">
  <div class="modal-body">

      <div class="row pad-top">
        <div class="col">
          <input type="text" class="form-control" placeholder="First name" id="first-name-id" oninput="enable_save_customer_button()">
        </div>
        <div class="col">
          <input type="text" class="form-control" placeholder="Last name" id="last-name-id" oninput="enable_save_customer_button()">
        </div>
      </div>

      <div class="col">
        <br>
        <div class="input-group">
        <div class="input-group-prepend form-label-group">
        <div class="input-group-text">Tail #</div>
        </div>
            <input name="pseudo-tail" type="text" class="form-control" id="save-tail-text-id" placeholder="Not entered (this is a bug, please report it)" disabled>
        </div>
      </div>

      <div class="col">
        <div class="input-group">
        <div class="input-group-prepend form-label-group">
        <div class="input-group-text">Aircraft type</div>
        </div>
            <input name="pseudo-tail" type="text" class="form-control" id="save-aircraft-text-id" placeholder="Not entered" disabled>
        </div>
      </div>

  </div>

    {% csrf_token %}  <!-- A second csrf_token that shouldn't be the issue -->
      <div class="modal-footer">
        <button type="button" class="btn btn-secondary" data-dismiss="modal" id="cancel-button-id">Cancel</button>
        <!-- Button type "submit" causes Django view to be called -->
        <button type="submit" class="btn btn-primary add-todo" id="save-customer-button-id" name="save_customer" value="save_customer" formmethod="POST">Save customer info</button>
        <!-- An actual POST response depends on if it's specified in the form tag above -->
      </div>
</form>

那么我应该做些什么不同的事情才能在同一页面上拥有 2 个工作表单?我还能提供其他信息吗?谢谢。

【问题讨论】:

    标签: html django django-forms django-views


    【解决方案1】:

    解决了我自己的问题。最重要的是,“名称”属性必须位于您的输入字段所在的位置,而我错过了这些。 Django 使用名称字段(不是 ID 或值)来检索每个字段的输入值。这是我的疏忽 - 几天前表单确实有效,所以看起来我出于测试目的删除了名称属性并忘记了。

    此外,请确保您在进行这些更改时确实提交了表单。从我的角度来看,这并没有解决我的表单似乎自动提交/发布(无论正确的术语是什么)的问题。但我确实注意到 csrf_token 保持一致(以及任何字段数据),直到用户发布新请求。这似乎很明显,但为了对像我这样的初学者安全起见,请务必告诉 Django 你对表单进行了更改。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-12-04
      • 2018-12-17
      • 2020-08-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-08
      相关资源
      最近更新 更多