1

次のようにmodelformset_factoryを使用してフォームセットを作成する場合:

 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()

ちなみに、このメソッドでは、フォームセット内の各フォームを取得してform.save(commit = False)を実行することを考えると、カスタム.save()も実行できると思います。ただし、レシピオブジェクトにアクセスする必要があるため、自分のビューでそれを行う方が簡単でした。

4

1 に答える 1

1

save()BaseModelFormの既存のメソッドをオーバーライドする最善の方法がわかりません。私の推測では、あなたは実際に次のいずれかをしたいと思うでしょう:

  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. フォームセットでsave(commit = False)を使用し、材料のルックアップ/作成を実行してから、コミットします

于 2012-04-25T19:52:21.950 に答える