Изменить данные формы Django до их обработки - PullRequest
5 голосов
/ 29 сентября 2010

У меня есть форма для модели, которая имеет два поля: field_A и field_B. Я хочу:

  • при отображении формы: отображается только field_A
  • когда я вызываю form.save () field_B сохраняется в модели со значением из field_A

Что я пробовал:

field_A = forms.CharField(required=True)
field_B = forms.CharField(required=False)

def save(self, *args, **kwargs):
     """
     Overriding save, so call the parent form save and return the new_user
     object.
     """
     self.data["field_B"] = self.data["field_A"]
     self.cleaned_data["username"] = self.cleaned_data["email"]
     super(MyParentClass*, self).save(*args, **kwargs) 

* оба поля унаследованы от ParentClass, где они обязательны для заполнения

1 Ответ

5 голосов
/ 29 сентября 2010

Вот решение, которое сработало для меня.

# models.py
class MyModel(models.Model):
    field_A = models.CharField(max_length = 255)
    field_B = models.CharField(max_length = 255)

    def __unicode__(self):
        return "%s: %s, %s" % (self.pk, self.field_A, self.field_B)

# forms.py
class MyModelForm(ModelForm):
    class Meta:
        model = MyModel
        exclude = ('field_B',)

    def save(self, *args, **kwargs):
        commit = kwargs.pop('commit', True)
        instance = super(MyModelForm, self).save(*args, commit = False, **kwargs)
        instance.field_B = self.cleaned_data['field_A']
        if commit:
            instance.save()
        return instance

Объяснение формы Meta

exclude = ('field_B',)

Гарантирует, что ваше первое условие выполнено.Когда форма показывается пользователю, отображается только field_A.Второе условие рассматривается в переопределенном методе save().

Объяснение save()

commit = kwargs.pop('commit', True)

Извлечь аргумент ключевого слова commit, если он указан.1021 *

instance = super(MyModelForm, self).save(*args, commit = False, **kwargs)

Создать экземпляр базовой модели.Явно передайте commit=False, чтобы этот экземпляр еще не был сохранен в базе данных.

instance.field_B = self.cleaned_data['field_A']

Назначьте значение field_A из cleaned_data для field_B экземпляра.Помните, что вы должны были позвонить form.is_valid() до этого.Иначе не будет cleaned_data.

        if commit:
            instance.save()

Если пользователь хочет, чтобы экземпляр был сохранен в базе данных, сделайте это.

return instance

Наконец, верните экземпляр.

Использование образца

In [1]: from app.forms import MyModelForm

In [2]: f = MyModelForm(data = {'field_A': 'Value A'})

In [3]: f.is_valid()
Out[3]: True

In [4]: f.save()
Out[4]: <MyModel: 3: Value A, Value A>

In [5]: f = MyModelForm(data = {'field_A': 'VA'})

In [6]: f.is_valid()
Out[6]: True

In [7]: f.save(commit = False)
Out[7]: <MyModel: None: VA, VA>

In [8]: 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...