Django(主干)和基于类的通用视图:一个表单的初始数据出现在另一个表单中
我遇到了一个奇怪的问题,数据似乎在不同的视图和请求中持续存在,直到服务器重新启动。
我已设法将问题减少为以下代码:
# 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
中):
<form action="" method="post">
{{ form.as_p }}
<input type="submit" />
{% csrf_token %}
</form>
要重现,请执行以下操作:
- 添加 foobar应用程序到
settings.INSTALLED_APPS
- 运行
syncdb
- 将
foobar.urls
添加到您的根 urlconf - 导航到
/foobar/
(实际的 URL 将取决于您的根 urlconf) - 提交表单(从而创建一个新的 Foo 对象)
- 导航到
/foobar/1/
。请注意,表单字段已预先填充(这是预期的) - 导航到
/foobar/
。请注意,表单字段仍然被填充(这不是预期的)。
这是一个错误还是我做了一些我不应该做的事情(或者也许两者都是......)?
-- 编辑 --
在 forms.py 中,如果我将 update
调用替换为:
kwargs['initial']['bug'] = 'WHY???'
那么问题仍然存在。
注释掉该行可以消除问题(但显然,表单没有初始数据)。
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',
('^
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:
- 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).
Is this a bug or am I doing something I shouldn't be (or maybe both...)?
-- EDIT --
In forms.py, if I replace the update
call by this:
kwargs['initial']['bug'] = 'WHY???'
Then the problem is still there.
Commenting out the line removes the problem (but then the form has no initial data, obviously).
, 'create'),
(r'^(?P<pk>\d+)/
You should also probably add a template (in foobar/templates/foo_form.html
for example):
To reproduce, do the following:
- 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).
Is this a bug or am I doing something I shouldn't be (or maybe both...)?
-- EDIT --
In forms.py, if I replace the update
call by this:
Then the problem is still there.
Commenting out the line removes the problem (but then the form has no initial data, obviously).
, 'update'),
)
You should also probably add a template (in foobar/templates/foo_form.html
for example):
To reproduce, do the following:
- 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).
Is this a bug or am I doing something I shouldn't be (or maybe both...)?
-- EDIT --
In forms.py, if I replace the update
call by this:
Then the problem is still there.
Commenting out the line removes the problem (but then the form has no initial data, obviously).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
因为您正在改变传入的 kwargs,这些 kwargs 来自视图类中的类级属性。
相反,复制它们并更新副本:
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:
你可能想要指定Django-1.3开发,通用类视图在Django 1.2.5中不存在。在您的
forms.py
文件中,您可以注释以下行并重试吗:You might want to specify Django-1.3 development, generic class view doesn't exist in Django 1.2.5. In your
forms.py
file, can you comment the following lines and try again: