2010-02-13 18 views
7

Sagen wir, ich bin mit dem Standard-auth.models.User und meine benutzerdefinierten Profile und Address Modelle, die wie folgt aussehen:Django-Modelle mit OneToOne-Beziehungen?

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) 

Jetzt möchte ich ein Anmeldeformular erstellen. Ich könnte eine ModelForm basierend auf User erstellen, aber das wird keine Felder für die Profile und Address (die erforderlich sind) enthalten. Was ist der beste Weg, dieses Formular zu erstellen? Sollte ich überhaupt ModelForm verwenden?

Außerdem, wie würde ich das gleiche Formular für die Bearbeitung des komplexen Objekts verwenden? Ich könnte leicht eine Instanz von Profile zurückgeben, die Referenzen auf die notwendigen Adress- und Profilobjekte enthält, aber wie bekomme ich es, um die Felder für mich auszufüllen?

+2

@Mark In Ihrem Beispiel haben Sie vor dem Erstellen die Adresse referenziert. Sie müssen es in Anführungszeichen setzen, um dies zu tun, oder "Profil" unter "Adresse" verschieben, wenn Sie keine Anführungszeichen verwenden möchten. – orokusaki

+0

@orokusaki: Ich denke, ich habe die von zwei verschiedenen Orten eingefügt, oder ich hätte einen Fehler bekommen. Wusste nicht, dass ich nur Zitate verwenden könnte. Vielen Dank. – mpen

Antwort

8

Was ist 3 separate ModelForm verwenden. Ein für Address, ein für User und ein für Profile aber mit:

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

Dann Verfahren dieser drei Formen separat in Ihren Ansichten.Insbesondere für die ProfileFormsave verwendet mit commit=Falseuser und address Feld auf der Instanz zu aktualisieren:

# ... 
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 

Zögern Sie nicht, Transaktionen zu verwenden hier sicher Reihen sein nur eingesetzt werden, wenn die drei Formen gültig sind.

+0

Sieht so aus, als ob das der richtige Weg ist. Ich bin nicht glücklich darüber, aber es ist das einzige, was funktioniert. Ich hätte mir ein "DeepModelForm" gewünscht, bei dem ForeignKeys/OneToOnes in eine eigene Form konvertiert werden, anstatt eine '