【问题标题】:Django UpdateView - no object due to POST callDjango UpdateView - 由于 POST 调用没有对象
【发布时间】:2018-06-01 19:03:13
【问题描述】:

我有两个 UpdateView,一个有效,另一个无效... 请参阅更新 IV

工作模式是:

views.py

class JuryUpdate(UpdateView):
    model = Jury
    fields = [
        'jury_name',
        ]
    template_name_suffix = '_update_form'

    def get_object(self, *args, **kwargs):
        return get_object_or_404(Jury, jury_id=self.kwargs['jr'])

    def form_valid(self, form):
        form.instance.customer_id = self.kwargs['pk']
        form.instance.court_year = self.kwargs['yr']
        form.instance.jury_id = self.kwargs['jr']
        return super(JuryUpdate, self).form_valid(form)

templates/jury_update_form.html(在相关部分)

<div class="container">
    <h5>Update {{for.instance.jury_name}}</h5>
    <form method="post">{% csrf_token %}
        {{ form.as_p }}
        <input type="submit" value="Save" />
    </form>
</div>

此设置将使用对象标签和对象中的现有字段数据呈现更新视图。下一个设置不起作用...

views.py

class CustomerUpdate(UpdateView):
    model = Customer
    fields = [
        'customer',
        ]
    template_name_suffix = '_update_form'

    def get_object(self, *args, **kwargs):
        return get_object_or_404(Customer, customer_id=self.kwargs['pk'])

    def form_valid(self, form):
        form.instance.customer_id = self.kwargs['pk']
        return super(CustomerUpdate, self).form_valid(form)

templates/customer_update_form.html(在相关部分)

<div class="container">
    <h5>Update {{form.instance.customer}}</h5>
    <form method="post">{% csrf_token %}
        {{ form.as_p }}
        <input type="submit" value="Save" />
    </form>
</div>

第二个 updateview 确实提供了一个更新表单,但它没有填充调用对象的数据。似乎该对象在那里,因为 {{form.instance.customer}} 包含正确的 customer 调用数据(与 JuryUpdate 视图没有什么不同)。

我尝试显式调用get_initial(如here 所述)并打印,但结果为{}。我也尝试了form_valid 调用的变体,但如上所述,我相信我得到了正确的对象。有几个示例(例如here)使用get_initial 预先填充现有信息 - 但在这种情况下不起作用,并且在我的JuryUpdate 视图中不需要。

感谢任何帮助。

更新我

models.py

class Customer(models.Model):

    class Meta:
        verbose_name = "Customer"
        verbose_name_plural = "Customers"

    customer_id = models.AutoField(
        primary_key=True)

    customer = models.CharField(
        max_length=40)

    # table fields

    def get_absolute_url(self):
        return reverse(
            'customer-detail-view', 
            kwargs={'pk':self.pk})

    def __str__(self):
        return self.customer

class Jury(models.Model):

    class Meta:
        verbose_name = "Jury"
        verbose_name_plural = "Juries"

    customer = models.ForeignKey(
        Customer,
        on_delete=models.CASCADE)

    court_year = models.ForeignKey(
        CourtYear,
        on_delete=models.CASCADE)

    jury_id = models.AutoField(
        primary_key=True)

    jury_name  = models.CharField(
        max_length=20)

    # other table fields

    def get_absolute_url(self):
        return reverse(
            'jury-list-view', 
            kwargs={'pk':self.customer_id, 'yr':self.court_year_id})

    def __str__(self):
        return self.jury_name

urls.py

path('add_customer/', views.CustomerCreate.as_view(), name='customer-add'),
path('<int:pk>/', views.CustomerDetailView.as_view(), name='customer-detail-view'),
path('<int:pk>/delete/', views.CustomerDelete.as_view(), name='customer-delete'),   
path('<int:pk>/update/', views.CustomerUpdate.as_view(), name='customer-update'),

path('<int:pk>/<int:yr>/', views.JuryListView.as_view(), name='jury-list-view'),
path('<int:pk>/<int:yr>/add_jury/', views.JuryCreate.as_view(), name='jury-add'),
path('<int:pk>/<int:yr>/<int:jr>/updatejury', views.JuryUpdate.as_view(), name='jury-update'),
path('<int:pk>/<int:yr>/<int:jr>/deletejury', views.JuryDelete.as_view(), name='jury-delete'),

更新 II

我在CustomerUpdate(UpdateView) 中添加了一个get_initial() 方法,如下所示:

def get_initial(self):

    initial = super(CustomerUpdate, self).get_initial()
    print('initial data', initial)

    customer_object = self.get_object()

    initial['customer'] = customer_object.customer
    # other fields omitted...

    print('initial data updated', initial)

    return initial

initial data 打印返回 {}initial data updated 打印返回 {'customer': 'John Doe'}(加上“其他字段”)。因此,似乎正确的信息正在被提取和传递 - 它必须在 html 中?

更新 III

我已经将CustomerUpdate(UpdateView) 带到了非常基本的类模型:

class CustomerUpdate(UpdateView):
    model = Customer
    fields = [
        'customer',
        ]
    template_name_suffix = '_update_form'

模板已经是基本格式 (docs) - 渲染的网页仍然没有更新的对象数据...

更新 IV

我想我已经找到了问题所在 - 但不知道如何解决...

当我使用JuryUpdate 调用控制台时显示:

[02/Jun/2018 16:19:19] "GET /myapp/1/3/9/updatejury/?csrfmiddlewaretoken=1kHK4xgqdbBfXsv6mtz0WKgKpewFwLVtpUX5Z51qnLsGaMDVmpdVHKslXAXPhvY8 HTTP/1.1" 200 3687

当我使用CustomerUpdate 调用控制台时显示:

[02/Jun/2018 16:18:57] "POST /myapp/5/update/ HTTP/1.1" 200 3354

因此,我对陪审团更新的 updateview 是 GET 调用,而我对 Customer 的 udpateview 是 POST 调用。在查看文档时,我可以看到 GET 调用显示数据,而 POST 调用(我认为)假设黑色数据集。我无法弄清楚为什么我会得到不同的结果 - 这将在哪里设置/更改?

【问题讨论】:

  • 在进一步查看之前 - CustomerUpdate 中的“客户”字段可能应该是小写的?不看你的模型就不可能确定,但​​你的叙述表明这是错误的大写。 (不过,这可能是也可能不是您的实际问题的原因。)
  • @JamesAylett - 我在 SO 上的错字 - 已修复。
  • 您的Customer 真的有customer 字段吗?这似乎……出乎意料。它强调这不是一个足够完整的视图来查看正在发生的事情——你的 urlconf 和模型可能需要有人来帮助。
  • 使用 Python 3,所以当 Python 2 失去所有支持时,您无需在一年半内重写此代码。
  • @Bill super() 在 Python 3 上不需要参数。大多数人不使用它,因为它违反了 DRY 规则并且使得重构类名变得更加困难。

标签: python django python-3.x django-views


【解决方案1】:

3 天后 - 我追踪了问题 - 它与视图、模型、url 或更新模板无关。有问题的代码实际上附加到更新按钮上。非常特别地,具有“更新”按钮的页面使用了以下&lt;form&gt; 代码:

<form action="{% url 'customer-update' pk=customer.client_id %}" method="post" style="display: inline;">
    {% csrf_token %}
    <button type="submit" class="btn btn-outline-primary btn-custom-xs">U</button>
</form>

在表单调用中,使用的方法是"POST" - 虽然我不完全理解其中的内容,但结果是一个空白的 UpdateView。调用页面中的以下代码解决了问题。

<form action="{% url 'customer-update' pk=customer.client_id %}" style="display: inline;">
    {% csrf_token %}
    <button type="submit" class="btn btn-outline-primary btn-custom-xs">U</button>
</form>

【讨论】:

    猜你喜欢
    • 2017-05-13
    • 2021-10-01
    • 2017-10-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-19
    • 2019-01-19
    相关资源
    最近更新 更多