且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

Django:同时保存多个模型(复杂情况)

更新时间:2022-10-14 23:04:59

ModelForm s?

  if request.method =='POST'
uform = UserCreationForm(request.POST,prefix ='user')
sform = SiteForm(request.POST,prefix ='site')
oform = OrgForm(request.POST,prefix ='网站')
如果uform.is_valid()和sform.is_valid()和oform.is_valid():
#save返回对象
user = uform.save()

#commit = false不保存到DB。
site = sform.save(commit = False)
site.user = user
site.save()

org = oform.save(commit = False)
org.user = user
org.save()

有关评论的更新:为什么在一个地方可以将这个表单传播到多个区域和文件(信号,表单保存)中?



代码更可读,甚至可以保存代码行。除非它将在全球范围内使用。


Well, it may actually be a simple case but I'm having a tough time figuring it out.

I have two user registration funnels (corporate & everyone else). When a corporate user creates a User instance through my registration form, I would also like them to input secondary forms that create related instances (based on the Website and Organization_Contact models).

I know how to solve this by making additional synchronous or asynchronous requests, but I'd like the user to fill out the three forms and submit with one click.

My issue here is that the other two forms rely on a User foreign key as a field. I've made that field "null=True, blank=True" so that I can validate and save the forms without the foreign key, but I ultimately want to add that key to both model instances.

I thought that I could validate the three forms, save the UserForm, and then use a model queryset to return the new User.id (all in one view). I would then add that user_id value to the other two form dictionaries (WebsiteForm and Organization_ContactForm).

It would work as so:

def register_company(request):
    if request.method=='POST'
       uform=UserCreationForm(request.POST, prefix='user')
       sform=SiteForm(request.POST, prefix='site')
       oform=OrgForm(request.POST, prefix='site')
       if uform.is_valid() and sform.is_valid() and oform.is_valid():
            uform.save()
            user=User.objects.get(email__iexact=uform.cleaned_data['email'])
            uid=unicode(user.id)
       #now I'd add uid back into the SiteForm and Orgform dictionaries and then save both instances              

Problems: 1) Not sure if I can save a modelform and then return that model instance as a queryset in a single view

2)I say that I'm not sure because I couldn't get passed the problem of trying to pass a variable to the queryset.

The get manager method seems to not accept a variable there. I assume as much because I passed an equivalent hardcoded string and it worked.

Ok, so I was thinking about creating a new manager method (email) which accepted a variable argument (the cleaned email field) and then retrying the process of saving one modelform, retrieving the model id data, and saving the other modelforms.

I also thought that I might be able to handle this issue through a post save signal.

Just general direction here would be really helpful. I need a starting point

Thanks!

Are these all ModelForms?

if request.method=='POST'
   uform=UserCreationForm(request.POST, prefix='user')
   sform=SiteForm(request.POST, prefix='site')
   oform=OrgForm(request.POST, prefix='site')
   if uform.is_valid() and sform.is_valid() and oform.is_valid():
        # save returns the object 
        user = uform.save()

        # commit = false doesn't save to DB.
        site = sform.save(commit=False)
        site.user = user
        site.save()

        org = oform.save(commit=False)
        org.user = user
        org.save()

Update regarding comments: Why spread this form saving logic around into multiple areas and files (signals, form save) when you can do it in one place?

The code is more readable, and you even save lines of code. Unless it's going to be used globally.