que tienen un método en mi formulario de registro de usuario que tiene este aspecto:Cascada Django guardar?
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
El problema es que cuando llamo form.save()
se crea el objeto user
como se esperaba, pero no salva a su perfil o dirección. ¿Por qué no se conecta en cascada y guarda todos los submodelos? Sospecho que podría llamar al user.profile.save()
y al user.profile.address.save()
manualmente, pero quiero que todo funcione bien o falle al mismo tiempo. ¿Cuál es la mejor manera de hacer esto?
solución actual:
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()
tuviera que hacer profile
el objeto "central". Necesario para establecer profile.user = user
en lugar de user.profile = profile
para que funcione (supongo que porque la clave está en el modelo de perfil, no en el modelo de usuario). solución
reciente:
me dio un indicio de this article sugerido en this answer.
Ahora he separado de mis modelos de formularios y se trasladó la lógica a la vista:
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)
)
no soy demasiado aficionado a trasladar la carga a la vista, pero creo que tengo un poco más de flexibilidad este ¿camino?
¡Buen espectáculo! – jathanism