Создание одной формы Django для сохранения двух моделей

У меня есть обычная модель Django User и модель UserDetails (OneToOneField с User), которая служит расширением для модели User. (Я пробовал функцию Django 1.5, и это была головная боль с странно ужасной документацией, поэтому я придерживался опции OneToOneField)

Итак, в своем стремлении создать пользовательскую страницу регистрации, которая будет иметь регистрационную форму, состоящую из полей User и полей UserDetails, я задался вопросом, есть ли способ создать форму автоматически (со всеми его валидации) из этих двух связанных моделей. Я знаю, что это работает для формы, сделанной из одной модели:

class Meta:
    model = MyModel

Но есть ли вообще такая же функциональность для формы, состоящей из двух связанных моделей?

Ответ 1

from django.forms.models import model_to_dict, fields_for_model


class UserDetailsForm(ModelForm):
    def __init__(self, instance=None, *args, **kwargs):
        _fields = ('first_name', 'last_name', 'email',)
        _initial = model_to_dict(instance.user, _fields) if instance is not None else {}
        super(UserDetailsForm, self).__init__(initial=_initial, instance=instance, *args, **kwargs)
        self.fields.update(fields_for_model(User, _fields))

    class Meta:
        model = UserDetails
        exclude = ('user',)

    def save(self, *args, **kwargs):
        u = self.instance.user
        u.first_name = self.cleaned_data['first_name']
        u.last_name = self.cleaned_data['last_name']
        u.email = self.cleaned_data['email']
        u.save()
        profile = super(UserDetailsForm, self).save(*args,**kwargs)
        return profile

Ответ 2

Один из способов добиться этого, если вы хотите, чтобы модель ModelForm для User и UserDetails была отдельной, должна была возвращать обе формы в интерфейс, и убедиться, что они оба находятся в одном и том же элементе формы html (т.е. все поля будет возвращен при публикации данных).

Это работает, если Пользователь и UserDetails не имеют полей с тем же именем. Чтобы ввести данные в каждый экземпляр ModelForm, вы используете обычный метод:

    form_user = UserForm(request.POST, instance=request.user)
    form_user_details = UserDetailsForm(request.POST, instance=request.user.userdetails)