【问题标题】:how to overwrite save method in django model form如何以 django 模型形式覆盖保存方法
【发布时间】:2021-08-11 22:52:40
【问题描述】:

我正在尝试覆盖我的 forms.py 中的保存方法,我必须防止创建重复的对象,如果对象存在只更新一些字段

class Item(models.Model):
    item = models.ForeignKey(Product,on_delete=models.CASCADE)
    quantity = models.IntegerField()

例如,如果我之前输入了此数据:item = XYZ , quantity = 100 我想阻止创建另一个 XYZ 项目,我只想更新数量,例如我将输入此数据item = XYZ , quantity = 200 我试图阻止创建这个重复的数据,我只是尝试更新数量previous quantity + new quantity100 + 200 = 300我必须更新quantity to 300为此我覆盖save()在我的forms.py

class ItemForm(forms.ModelForm):
    class Meta:
        model = Item
        fields = ['item','quantity']

    def save(self,*args,**kwargs):
        if self.instance.item is None: #i also tried this if not self.instance.item
            return super().save(*args,**kwargs)      
        else:
            Item.objects.filter(item__name=self.instance.item).update(
               quantity=F('quantity') + self.instance.quantity)            

我的意见.py

def createNewProduct(request):
   form = ItemForm()
   if request.method == 'POST':
       form = ItemForm(request.POST)
       if form.is_valid():           
            form.save()

   return render(request,'temp/add_item.html',{'form':form})

但它只在它存在时更新,如果不存在它不会创建任何新对象,如果它不存在,我希望创建新对象,请问有没有办法实现它?还是我没有错?

【问题讨论】:

    标签: python django


    【解决方案1】:

    这就是我通常以模型形式覆盖保存方法的方式:

    def save(self, commit=True):
        # your logic or Save your object for example:
        obj = Model.objects.create(...)
        return obj  
    

    或者你也可以这样做:

    def save(self, commit=True): 
        obj = super().save(commit=False)
        # do you logic here for example:
        obj.field = something
        
        if commit:
            # Saving your obj
            obj.save()
        return obj
    

    【讨论】:

    • 不行,试了好几次都不行
    • 你的意思是它不起作用。我已经做了好几次了......你的意思是它不保存你的 obj ?
    【解决方案2】:

    根据documentation for ModelForm.save():

    ModelForm 的子类可以接受现有模型实例作为 关键字参数实例;如果提供,save() 将更新 那个例子。如果未提供, save() 将创建一个新实例 指定型号的。

    这意味着在你的 createNewProduct 视图中,当处理 POST 请求时,你需要检查一个 Item 是否已经存在于数据库中,如果存在则将它传递给 Form 构造函数进行编辑,否则实例化ModelForm 像往常一样创建一个新项目。所以其实不需要重写ModelForm的save方法

    由于您想添加新旧数量而不是覆盖它们,因此您需要在保存表单之前处理好这一点。这通常应该发生在表单的 clean 方法中。

    生成的 ItemForm 和 createNewProduct 视图将如下所示:


    class ItemForm(forms.ModelForm):
          class Meta:
              model = Item
              fields = ['item','quantity']
    
          def clean(self):
              cleaned_data = super().clean()
    
              # if this Item already exists
              if self.instance:
                 # add the old quantity to the new quantity
                 cleaned_data['quantity'] += self.instance.quantity
              return cleaned_data
    
    def createNewProduct(request):
    
       if request.method == 'POST':
           try:
               dbItem = Item.objects.get(item=request.POST['item'])
           except Item.DoesNotExist:
               # get form for new Item
               form = ItemForm(request.POST)
           else:
               # get form for existing Item
               form = ItemForm(request.POST,instance=dbItem)
           finally:
               if form.is_valid():
                  form.save()
                  return redirect('success') # redirect on success
               return redirect('failure') #redirect on failure 
       else:
           form = ItemForm()
    
       return render(request,'temp/add_item.html',{'form':form})  
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-10-07
      • 1970-01-01
      • 1970-01-01
      • 2010-10-31
      • 1970-01-01
      • 2020-08-07
      • 2021-11-21
      相关资源
      最近更新 更多