В Django, как я могу создать пользователя и профиль пользователя одновременно из одной отправки формы - PullRequest
4 голосов
/ 28 сентября 2011

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

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

Мой подход к этому состоял в том, чтобы использовать две формы и объединить их в одном шаблоне с помощью одной кнопки отправки.

Форма отображается точно так, как я хотел, и правильно возвращает ошибки проверки, но, как и ожидалось, она падает, когда дело доходит до сохранения в базе данных.Когда я вызываю save () в пользовательской форме, пользователь создается, но, конечно, когда я пытаюсь сохранить форму userprofile, он выдает ошибку, потому что пользователь еще не существует, поэтому с ним не связан пользователь.

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

Я включилвесь мой код ниже, включая модель, а также формы и представление на всякий случай, если это поможет любому лучше понять, что я пытаюсь сделать:

класс UserProfile (models.py)

LEVEL = (
    ('admin', 'administrator'),
    ('team', 'team leader'),
    ('member', 'team member'),
)

class UserProfile(models.Model):
    user = models.ForeignKey(User, unique=True)
    level = models.CharField(choices=LEVEL, max_length=20)

Классы UserCreationForm и UserProfileForm (forms.py)

class UserCreationFormExtended(UserCreationForm): 
    def __init__(self, *args, **kwargs): 
        super(UserCreationFormExtended, self).__init__(*args, **kwargs) 
        self.fields['first_name'].required = True
        self.fields['last_name'].required = True

    class Meta: 
       model = User 
       fields = ('username', 'email', 'first_name', 'last_name') 


class UserProfileForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super(UserProfileForm, self).__init__(*args, **kwargs)  

         self.fields["level"].choices = ( ('admin', 'administrator'), ('team', 'team leader'), ('member', 'team member') )

    class Meta:
        model = UserProfile

представление use_add (views.py)

def user_add(request):

    if request.method == 'POST':
        uform = UserCreationFormExtended(request.POST)
        pform = UserProfileForm(request.POST)

        if uform.is_valid():

            uform.save()
            pform.save()

            return render_to_response('user/add_success.html', context_instance=RequestContext(request))

        else:
            return render_to_response('user/add.html', { 'uform' : uform, 'pform' : pform }, context_instance=RequestContext(request))

    else:
        uform = UserCreationFormExtended()
        pform = UserProfileForm()

        return render_to_response('user/add.html', { 'uform' : uform, 'pform' : pform }, context_instance=RequestContext(request))

Ответы [ 2 ]

8 голосов
/ 28 сентября 2011

Сначала добавьте exclude = ('user',) в мета-класс для ProfileForm. Тогда, по вашему мнению:

user_valid = uform.is_valid()
profile_valid = pform.is_valid()
if user_valid and profile_valid:
    user = uform.save()
    profile = pform.save(commit=False)
    profile.user = user
    profile.save()

Хотя мне приходит в голову, что, поскольку у вас есть только одно поле в форме профиля, более простой способ сделать это - полностью забыть эту форму и просто добавить поле в форму пользователя:

class UserCreationFormExtended(UserCreationForm): 
    level = forms.ChoiceField(choices=LEVEL, max_length=20)
    ... etc...

if uform.is_valid():
    user = uform.save()
    profile = Profile.objects.create(user=user, level=uform.cleaned_data['level']))
0 голосов
/ 02 ноября 2012

Здесь есть похожее решение: http://sontek.net/blog/detail/extending-the-django-user-model

По сути, вы просто расширяете стандартную форму UserCreationForm, но сохраняете то же имя.Делая это таким образом, вам не нужно добавлять какие-либо новые представления или что-то в этом роде, это работает безупречно с тем, как документы Django говорят вам делать UserProfiles.

Честно говоря, я не понимаю, почему они объясняют, как добавить поля на страницу администратора, а затем не говорят вам, как на самом деле использовать эти поля в любом месте.

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