问题描述
我的用户注册表单中有一个方法,如下所示:
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 =个人资料(
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()
返回用户
问题是当我打电话 form.save()
它按预期创建用户
对象,但不保存他的个人资料或地址。为什么不级联并保存所有的子模型?我怀疑我可以手动调用 user.profile.save()
和 user.profile.address.save()
但我想让整个事情成功或失败在一起。这是最好的方法?
当前解决方案:
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 =个人资料(
primary_phone = self.cleaned_data ['phone'],
)
profile.address = address
profile.user = user
profile.save()
我必须使个人资料
中心对象。需要设置 profile.user = user
而不是 user.profile = profile
使其正常工作(我猜是因为关键在于个人资料模型,而不是用户模型)。
较新的解决方案:
我从建议在。
现在我已经分离了我的模型表单,并将逻辑移动到视图中:
$ b $如果request.POST:
account_type_form = forms.AccountTypeForm(request.POST)
user_form = forms,则
$ b $ _ UserForm(request.POST)
profile_form = forms.ProfileForm(request.POST)
address_form = forms.AddressForm(request.POST)
如果使用r_form.is_valid()和profile_form.is_valid()和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 /')
其他:
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)
)
我不太喜欢把负担转移到的看法,但我认为我以这种方式获得更多的灵活性?
它没有级联保存,因为它实际上不知道是否或者不需要保存其他对象需要。
要一次性执行,首先:
@ transaction.commit_on_success
def save(self):
....
然后按顺序保存子对象:
user.profile.address.save )
user.profile.save()
user.save()
I have a method on my user registration form that looks like this:
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 is when I call form.save()
it creates the user
object as expected, but doesn't save his profile or address. Why doesn't it cascade and save all the sub-models? I suspect I could call user.profile.save()
and user.profile.address.save()
manually, but I want the whole thing to succeed or fail together. What's the best way to do this?
Current solution:
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()
I had to make profile
the "central" object. Needed to set profile.user = user
rather than user.profile = profile
to make it work (I guess because the key is on the profile model, not on the user model).
Newer solution:
I took a hint from this article suggested in this answer.
Now I have separated my model forms and moved the logic into the view:
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)
)
I'm not too fond of shifting the burden to the view, but I guess I get a bit more flexibility this way?
It doesn't cascade-save because it doesn't actually know whether or not the other objects need to be saved.
To do it in one go, first start a transaction:
@transaction.commit_on_success
def save(self):
....
Then save the subobjects in order:
user.profile.address.save()
user.profile.save()
user.save()
这篇关于Django级联保存?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!