且构网

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

django中的需要的地方: form.save(commit=False)之后需要form.save_m2m() 来保存关联信息

更新时间:2022-08-31 15:43:42

django中的需要的地方: form.save_m2m() 

有这样的一个场景。

举个博客的例子吧,登录之后,写博客,然后保存博客的内容。博客的有些内容是在界面上由用户填写的,有些内容是在后台添加的。例如,用户姓名之类的。同时,还会有博客所属的分类。

下面是一个Blog的model和form的定义。

 


  1. class Blog(models.Model): 
  2.      
  3.     LIVE_STATUS=1 
  4.     DRAFT_STATUS=2 
  5.     HIDDEN_STATUS=3 
  6.     STATUS_CHOICES=( 
  7.     (LIVE_STATUS,'Live'), 
  8.     (DRAFT_STATUS,'Draft'), 
  9.     (HIDDEN_STATUS,'Hidden'
  10.     ) 
  11.     status=models.IntegerField(choices=STATUS_CHOICES,default=LIVE_STATUS,help_text='only entries with live status will be publicly displayed'
  12.      
  13.     lives=BlogLiveManager() 
  14.     objects=models.Manager() 
  15.      
  16.     title=models.CharField(max_length=100
  17.     slug=models.CharField(max_length=100
  18.     excerpt=models.TextField() 
  19.     content=models.TextField() 
  20.     author=models.ForeignKey(User) 
  21.     categories=models.ManyToManyField(Category) 
  22.     tags=models.ManyToManyField(Tag) 
  23.      
  24.     created_at=models.DateTimeField(editable=False
  25.     updated_at=models.DateTimeField(editable=False
  26.          
  27.      
  28.     def __unicode__(self): 
  29.         return self.title 
  30.      
  31.     def save(self,*args,**kwargs): 
  32.         if not self.id: 
  33.             self.created_at=datetime.datetime.now() 
  34.         self.updated_at=datetime.datetime.now() 
  35.          
  36.         super(Blog,self).save(*args,**kwargs) 
  37.      
  38.     class Meta: 
  39.         ordering=["-updated_at"
  40.          
  41.  
  42.  
  43. class BlogForm(forms.ModelForm): 
  44.     prepopulated_fields={'slug':("title")} 
  45.      
  46.     categories = forms.ModelMultipleChoiceField( 
  47.                             queryset=Category.objects.all(), 
  48.                             widget=forms.CheckboxSelectMultiple()) 
  49.     tags=forms.ModelMultipleChoiceField( 
  50.                             queryset=Tag.objects.all(), 
  51.                             widget=forms.CheckboxSelectMultiple()) 
  52.      
  53.     class Meta: 
  54.         model=Blog 
  55.         exclude=["author"
  56.         #fields=('title','categories') 

 下面是对应的新建时候用来保存的view的代码

 


  1. @login_required 

  1. new_blog=form.save()  
def blog_new(request):      current_user=request.user      if request.method=="POST"         form=BlogForm(data=request.POST)          if form.is_valid():                            #new_blog=form.save()                            new_blog=form.save(commit=False             new_blog.author=current_user              new_blog.save()              form.save_m2m()                            return redirect('/admin/blog_list'     else         form=BlogForm()      return render_to_response('admin/blog.html'                     {'form':form,'current_user':current_user})       

 

保存blog的信息直接调用

 


  1. new_blog=form.save()  

就可以实现,blog的基本信息和所属分类的信息分别保存在blog表和blog_category表。但是blog的用户信息,由于没有办法从界面收集,也不能让用户选择,就应该是当前用户的信息,所以需要在代码中赋值。

这样的话就需要在form.save()方法中传递一个参数commit,赋值为False,代表不要提交到数据库。然后给blog.author赋值,然后有两种选择。

1. 一种是调用new_blog.save()保存blog的基本信息,然后在调用form.save_m2m()保存关联信息,如果不调用save_m2m()的话,就会发现关联信息没有保存,就是由于之前使用了commit=False,影响了关联信息的保存,所以这里需要调用form.save_m2m()。

2. 一种是再次调用form.save()保存blog基本信息以及关联信息。




本文转自 virusswb 51CTO博客,原文链接:http://blog.51cto.com/virusswb/794680,如需转载请自行联系原作者