2013-04-08 4 views
11

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

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

class Meta: 
    model = MyModel 

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

+0

Да там, просто сделать свою собственную форму модели, которые вы можете расширить в функции инициализации с пользовательской экономии Fn. – Neal

+2

@Neal Можете ли вы, пожалуйста, подробно остановиться на этом примере, если это возможно, и отправить его в качестве ответа, чтобы я мог принять его? – Orca

+0

Я не знаю, как я могу разработать ... Единственное, что я хотел бы ответить, это именно то, что в моем комментарии выше ... – Neal

ответ

13
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 
+0

выглядит хорошо, но не должен соответствовать классу Meta: model = UserDetails, а не model = UserDetailsForm? Кроме того, предположим, что UserDetails имеет поле под названием phoneNumber (с регулярным выражением для \ d {10}), форма автоматически позаботится об этом, поскольку вы положили его (потому что он связан с моделью UserDetails) или мне нужно изменить код выше ? Спасибо – Orca

+0

извините мою ошибку. Вы должны изменить его, потому что я только ставил общие поля для пользователя – catherine

+0

. Еще два вопроса: 1- Если мне нужно добавить пользовательские поля UserDetails (например, телефон), где я должен сделать ссылку на него в приведенном выше коде, или django сделает это для меня автоматически, потому что класс meta теперь указывает на UserDetails? 2- Как насчет других полей пользователя (пароль, имя пользователя)? Должен ли я добавить их в ваш код, или Django позаботится об этом? – Orca

4

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

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

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

Помня о том, что пользователь все еще не зарегистрирован, не запрашивал бы. userer ничего не указывает (или анонимный пользователь) ? – Orca

+0

Правильно, это указывает на AnonymousUser. Я просто показывал случай, когда вы снова будете использовать форму позже. – legrisdev

Смежные вопросы