Ich habe eine Methode auf meinem Benutzeranmeldeformular, das wie folgt aussieht:Djangokaskade speichern?
def save(self):
user = User(
username = self.cleaned_data['username'],
email = self.cleaned_data['email1'],
first_name = self.cleaned_data['first_name'],
last_name = self.cleaned_data['last_name'],
)
user.set_password(self.cleaned_data['password1'])
user.profile = Profile(
primary_phone = self.cleaned_data['phone'],
)
user.profile.address = Address(
country = self.cleaned_data['country'],
province = self.cleaned_data['province'],
city = self.cleaned_data['city'],
postal_code = self.cleaned_data['postal_code'],
street1 = self.cleaned_data['street1'],
street2 = self.cleaned_data['street2'],
street3 = self.cleaned_data['street3'],
)
user.save()
return user
Problem ist, wenn ich form.save()
nenne es schafft das user
Objekt wie erwartet, aber nicht sein Profil oder Adresse speichern. Warum kaskadiert und speichert es alle Untermodelle? Ich vermute, dass ich user.profile.save()
und user.profile.address.save()
manuell aufrufen könnte, aber ich möchte, dass das Ganze erfolgreich ist oder zusammen versagt. Was ist der beste Weg, dies zu tun?
Aktuelle Lösung:
def save(self):
address = Address(
country = self.cleaned_data['country'],
province = self.cleaned_data['province'],
city = self.cleaned_data['city'],
postal_code = self.cleaned_data['postal_code'],
street1 = self.cleaned_data['street1'],
street2 = self.cleaned_data['street2'],
street3 = self.cleaned_data['street3'],
)
address.save()
user = User(
username = self.cleaned_data['username'],
email = self.cleaned_data['email1'],
first_name = self.cleaned_data['first_name'],
last_name = self.cleaned_data['last_name'],
)
user.set_password(self.cleaned_data['password1'])
user.save()
profile = Profile(
primary_phone = self.cleaned_data['phone'],
)
profile.address = address
profile.user = user
profile.save()
Ich hatte profile
das "zentrale" Objekt zu machen. Benötigt, um profile.user = user
statt user.profile = profile
zu setzen, damit es funktioniert (ich denke, weil der Schlüssel auf dem Profilmodell ist, nicht auf dem Benutzermodell).
Neuere Lösung:
Ich nahm einen Hauch von this article vorgeschlagen in this answer.
Jetzt habe ich mein Modell Formen getrennt und bewegt die Logik in die Ansicht:
def register(request):
if request.POST:
account_type_form = forms.AccountTypeForm(request.POST)
user_form = forms.UserForm(request.POST)
profile_form = forms.ProfileForm(request.POST)
address_form = forms.AddressForm(request.POST)
if user_form.is_valid() and profile_form.is_valid() and address_form.is_valid():
user = user_form.save()
address = address_form.save()
profile = profile_form.save(commit=False)
profile.user = user
profile.address = address
profile.save()
return HttpResponseRedirect('/thanks/')
else:
account_type_form = forms.AccountTypeForm()
user_form = forms.UserForm()
profile_form = forms.ProfileForm()
address_form = forms.AddressForm()
return render_to_response(
'register.html',
{'account_type_form': account_type_form, 'user_form': user_form, 'address_form': address_form, 'profile_form': profile_form},
context_instance=RequestContext(request)
)
Ich bin nicht allzu gern die Last auf die Ansicht verschieben, aber ich denke, ich ein bisschen mehr Flexibilität erhalten diese Weg?
Jolly gute Show! – jathanism