2010-02-13 5 views
7

Скажем, я использую по умолчанию auth.models.User плюс мой обычай Profile и Address модели, которые выглядят так:Модели Django с отношениями OneToOne?

class Profile(models.Model): 
    user = models.OneToOneField(User) 
    primary_phone = models.CharField(max_length=20) 
    address = models.ForeignKey("Address") 

class Address(models.Model): 
    country = CountryField(default='CA') 
    province = CAProvinceField(default='BC') 
    city = models.CharField(max_length=80) 
    postal_code = models.CharField(max_length=6) 
    street1 = models.CharField(max_length=80) 
    street2 = models.CharField(max_length=80, blank=True, null=True) 
    street3 = models.CharField(max_length=80, blank=True, null=True) 

Теперь я хочу, чтобы создать регистрационную форму. Я мог бы создать ModelForm на основе User, но это не будет включать поля для Profile и Address (что необходимо). Итак, что лучший способ построить эту форму? Должен ли я вообще использовать ModelForm?

Кроме того, как бы я использовал ту же форму для редактирования сложного объекта? Я мог бы легко передать экземпляр профиля обратно к нему, который содержит ссылки на необходимые объекты Address и Profile, но как я могу его заполнить для меня полями?

+2

@Mark В вашем примере вы указали «Адрес» перед его созданием. Вам нужно будет обернуть его в кавычки, чтобы сделать это, или переместить «Профиль» ниже «Адрес», если вы не хотите использовать кавычки. – orokusaki

+0

@orokusaki: Я думаю, что вставил те из двух разных мест, или я бы ошибся. Не знал, что я могу просто использовать цитаты. Благодарю. – mpen

ответ

8

Что об использовании 3 отдельных ModelForm. Один для Address, один для User, и один для Profile но:

class ProfileForm(ModelForm): 
    class Meta: 
    model = Profile 
    exclude = ('user', 'address',) 

Затем процесс эти 3 формы отдельно в своих взглядах.В частности, для ProfileForm использовать save с commit=False обновить user и address поле на экземпляре:

# ... 
profile_form = ProfileForm(request.POST) 
if profile_form.is_valid(): 
    profile = profile_form.save(commit=False) 
    # `user` and `address` have been created previously 
    # by saving the other forms 
    profile.user = user 
    profile.address = address 

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

+0

Похоже, это путь. Я не доволен этим, но это единственное, что работает. Мне бы понравился некоторый «DeepModelForm», где ForeignKeys/OneToOnes преобразовывались в свою собственную форму, а не в «