本文介绍了Django级联保存?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的用户注册表单中有一个方法,如下所示:

  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级联保存?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-24 09:20