Django (транк) и родовые представления на основе классов: исходные данные одной формы появляются в другой - PullRequest
0 голосов
/ 16 февраля 2011

Я столкнулся со странной проблемой, когда данные, похоже, сохраняются в разных представлениях и запросах до перезапуска сервера.

Мне удалось свести проблему к следующему коду:

# 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???'

Тогда проблема все еще там.

Комментирование строки устраняет проблему (но тогда форма не имеет начальных данных, очевидно).

Ответы [ 2 ]

1 голос
/ 17 февраля 2011

Поскольку вы изменяете переданные kwargs, которые поступают из свойств уровня класса в классе представления.

Вместо этого скопируйте их и обновите копию:

initial_defaults = {'bug': 'no'}
initial_defaults.update(kwargs.get('initial', {}))
defaults = kwargs.copy()
defaults['initial'] = initial_defaults 
0 голосов
/ 16 февраля 2011

Возможно, вы захотите указать разработку Django-1.3, в Django 1.2.5 нет общего представления классов.В своем файле forms.py вы можете прокомментировать следующие строки и повторить попытку:

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)
...