Django(trunk)和基于类的通用视图:一个窗体的初始数据出现在另一个窗体中 [英] Django(trunk) and class based generic views: one form's initial data appearing in another one's

查看:165
本文介绍了Django(trunk)和基于类的通用视图:一个窗体的初始数据出现在另一个窗体中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到一个奇怪的问题,数据似乎在不同的视图和请求之间持续存在,直到服务器重新启动。

I've run into a strange problem where data seems to persist accross different views and requests until the server gets restarted.

我设法减少了问题到以下代码:

I've managed to reduce the issue to the following code:

# foobar/models.py
from django.db import models

class Foo(models.Model):
    bug = models.CharField(max_length=10)


# foobar/forms.py
from django import forms
from foobar.models import Foo

class CreateForm(forms.ModelForm):
    class Meta:
        model = Foo

class UpdateForm(forms.ModelForm):
    class Meta:
        model = Foo

    def __init__(self, *args, **kwargs):
        kwargs.setdefault('initial', {})
        kwargs['initial'].update({'bug': 'WHY??'})
        super(UpdateForm, self).__init__(*args, **kwargs)


# foobar/views.py
from django.views.generic.edit import CreateView, UpdateView
from foobar.forms import CreateForm, UpdateForm
from foobar.models import Foo

class FooCreateView(CreateView):
    form_class = CreateForm
    template_name = 'foobar/foo_form.html'

create = FooCreateView.as_view()

class FooUpdateView(UpdateView):
    form_class = UpdateForm
    template_name = 'foobar/foo_form.html'
    queryset = Foo.objects.all()

update = FooUpdateView.as_view()


# foobar/urls.py
from django.conf.urls.defaults import *

urlpatterns = patterns('foobar.views',
    ('^$', 'create'),
    (r'^(?P<pk>\d+)/$', 'update'),
)

您还应该添加一个模板(例如,在 foobar / templates / foo_form.html 中):

You should also probably add a template (in foobar/templates/foo_form.html for example):

<form action="" method="post">
{{ form.as_p }}
<input type="submit" />
{% csrf_token %}
</form>

要重现,请执行以下操作:

To reproduce, do the following:


  • 将foobar应用程序添加到 settings.INSTALLED_APPS

  • 运行 syncdb

  • foobar.urls 添加到您的根urlconf

  • 导航到(实际的URL将取决于你的root urlconf)

  • 提交表单(从而创建一个新的Foo对象)
  • 导航至 / foobar / 1 / 。请注意,表单域预填充(预期)

  • 导航到 / foobar / 。注意,表单字段仍然填充(这不是预期)。

  • Add the foobar app to settings.INSTALLED_APPS
  • Run syncdb
  • Add foobar.urls to your root urlconf
  • Navigate to /foobar/ (the actual URL will depend on your root urlconf)
  • Submit the form (thus creating a new Foo object)
  • Navigate to /foobar/1/. Notice that the form field is prepopulated (this is expected)
  • Navigate to /foobar/. Notice the form field is still populated (this is not expected).

这是一个bug还是我做某事我不应该(或者也可能是两个)?

Is this a bug or am I doing something I shouldn't be (or maybe both...)?

- 编辑 -

在forms.py中,如果我通过以下方式替换更新调用:

In forms.py, if I replace the update call by this:

kwargs['initial']['bug'] = 'WHY???'

那么问题仍然存在。

注释掉行删除了这个问题(但是这个表单显然没有初始数据)。

Commenting out the line removes the problem (but then the form has no initial data, obviously).

推荐答案

因为您正在变更传入的kwarg,它们来自视图类中的类级属性。

Because you're mutating the kwargs that are passed in, which come from class-level properties in the view class.

相反,复制它们并更新副本:

Instead, copy them and update the copy:

initial_defaults = {'bug': 'no'}
initial_defaults.update(kwargs.get('initial', {}))
defaults = kwargs.copy()
defaults['initial'] = initial_defaults 

这篇关于Django(trunk)和基于类的通用视图:一个窗体的初始数据出现在另一个窗体中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆