Django - 为modelformset_factory创建自定义.save()

时间:2012-04-25 19:19:49

标签: django forms django-forms

如果我使用modelformset_factory创建一个formset:

 IngredientFormSet = modelformset_factory(RecipeIngredients, form=RecipeIngredientsForm)
 formset = IngredientFormSet(request.POST)

我的表单看起来像这样

class RecipeIngredientsForm(forms.ModelForm):
    Ingredient = forms.CharField(max_length= 100)
    class Meta:
        model = RecipeIngredients
        exclude = ('weightmetric','recipe')

我将自定义.save()方法放在哪里?我会把它放在RecipeIngredientsForm下吗?

[潜在的解决方案]

在您的视图中执行以下操作:

 if formset.is_valid():
        for form in formset:
            obj = form.save(commit=False) #obj = RecipeIngredient model object
            try:
                ingredient_in_db = Ingredient.objects.get(name = form.cleaned_data.get('ingredientform'))
            except:
                ingredient_in_db = None
            if ingredient_in_db:
                obj.ingredient = ingredient_in_db
            else:
                new_ingredient = Ingredient.objects.create(name = form.cleaned_data.get('ingredientform'))
                obj.ingredient = new_ingredient
            obj.recipe = recipeobj
            obj.save()

顺便说一句,我认为这个方法也允许我做一个自定义的.save(),因为我在formset中获取每个表单并对其执行form.save(commit = False)。不过,在我的视图中这样做比较容易,因为我需要访问配方对象。

1 个答案:

答案 0 :(得分:1)

我不确定覆盖BaseModelForm上现有save()方法的最佳方法。我的猜测是你真的想要:

  1. 创建自己的字段,该字段具有自己的to_python()方法,该方法将获取文本并查找/创建关联对象。

    class IngredientField(forms.CharField):
        def to_python(self, value):
            # Lookup model or create new one
            ingredient = models.Ingredient.objects.get(name=value)
            if not ingredient:
                ingredient = models.Ingredient.create(name=value)
            return ingredient
    
  2. 在formset上使用save(commit = False),进行成分查找/创建,然后再提交