簡體   English   中英

如何使用視圖在Django中保存內聯表單集用戶字段

[英]How to save inline formset user field in Django using views

我一直在使用這篇很棒的文章http://kevindias.com/writing/django-class-based-views-multiple-inline-formsets/來設置我的網站。 我想知道如何將用戶字段自動保存到視圖中的內聯表單集中(我使用blockquote更改了原始內容)。 中的RecipeForm(有關上下文,請參見下文)

self.object = form.save(commit=False)
self.object.owner = self.request.user
self.object.save()

自動保存很好,但不保存

ingredient_form.owner= self.request.user

我知道Django建議使用BaseInlineFormSet ,但是出於許多不同的原因,大多數人建議將用戶字段保存在views.py中,而不是在表單或模型中保存。 我將不勝感激任何建議或答案。 這是完整的代碼:

models.py

from django.db import models


class Recipe(models.Model):
    owner = models.ForeignKey(User)
    title = models.CharField(max_length=255)
    description = models.TextField()


class Ingredient(models.Model):
    owner = models.ForeignKey(User)
    recipe = models.ForeignKey(Recipe)
    description = models.CharField(max_length=255)


class Instruction(models.Model):
    recipe = models.ForeignKey(Recipe)
    number = models.PositiveSmallIntegerField()
    description = models.TextField()

表格

from django.forms import ModelForm
from django.forms.models import inlineformset_factory 
from .models import Recipe, Ingredient, Instruction


class RecipeForm(ModelForm):
    class Meta:
        model = Recipe
    IngredientFormSet = inlineformset_factory(Recipe, Ingredient)
    InstructionFormSet = inlineformset_factory(Recipe, Instruction)

views.py

from django.http import HttpResponseRedirect
from django.views.generic import CreateView  
from .forms import IngredientFormSet, InstructionFormSet, RecipeForm
from .models import Recipe


class RecipeCreateView(CreateView):
    template_name = 'recipe_add.html'
    model = Recipe
    form_class = RecipeForm
    success_url = 'success/'

    def get(self, request, *args, **kwargs):
        """
        Handles GET requests and instantiates blank versions of the form
        and its inline formsets.
        """
        self.object = None
        form_class = self.get_form_class()
        form = self.get_form(form_class)
        ingredient_form = IngredientFormSet()
        instruction_form = InstructionFormSet()
        return self.render_to_response(
            self.get_context_data(form=form,
                                  ingredient_form=ingredient_form,
                                  instruction_form=instruction_form))

    def post(self, request, *args, **kwargs):
        """
        Handles POST requests, instantiating a form instance and its inline
        formsets with the passed POST variables and then checking them for
        validity.
        """
        self.object = None
        form_class = self.get_form_class()
        form = self.get_form(form_class)
        ingredient_form = IngredientFormSet(self.request.POST)
        instruction_form = InstructionFormSet(self.request.POST)
        if (form.is_valid() and ingredient_form.is_valid() and
            instruction_form.is_valid()):
            return self.form_valid(form, ingredient_form, instruction_form)
        else:
            return self.form_invalid(form, ingredient_form, instruction_form)

    def form_valid(self, form, ingredient_form, instruction_form):
        """
        Called if all forms are valid. Creates a Recipe instance along with
        associated Ingredients and Instructions and then redirects to a
        success page.
        """
        self.object = form.save(commit=False)
        self.object.owner = self.request.user
        self.object.save()
        ingredient_form.instance = self.object
        ingredient_form.owner= self.request.user
        ingredient_form.save()
        instruction_form.instance = self.object
        instruction_form.save()
        return HttpResponseRedirect(self.get_success_url())

    def form_invalid(self, form, ingredient_form, instruction_form):
        """
        Called if a form is invalid. Re-renders the context data with the
        data-filled forms and errors.
        """
        return self.render_to_response(
            self.get_context_data(form=form,
                                  ingredient_form=ingredient_form,
                                  instruction_form=instruction_form))

我做了一些進一步的研究,按照該指南的說明,該解決方案看起來有些復雜,該指南介紹了如何添加自定義 表單集 保存,但是如上所述對BaseInlineFormset進行了修改。 我意識到,為每個模型創建ModelForms然后在視圖中鏈接它們將更加簡單,因為在添加新配方視圖中一次只需要一個子表單,並且可以重用ModelForm代碼。

這是效果很好的新代碼! 如果您需要更多信息,請隨時聯系。

表格

from django.forms import ModelForm
from .models import Recipe, Ingredient, Instruction


class RecipeForm(ModelForm):

    class Meta:
        model = Recipe
        exclude = ['owner',]

class IngredientForm(ModelForm):

    class Meta:
        model = Ingredient
        exclude = ['owner','recipe',]

class InstructionForm(ModelForm):

    class Meta:
        model = Instruction
        exclude = ['recipe',]

views.py

from .forms import IngredientForm, InstructionForm, RecipeForm


def add_new_value(request):
    rform = RecipeForm(request.POST or None)
    iform = IngredientForm(request.POST or None)
    cform = InstructionForm(request.POST or None)
    if rform.is_valid() and iform.is_valid() and cform.is_valid():
        rinstance = rform.save(commit=False)
        iinstance = iform.save(commit=False)
        cinstance = cform.save(commit=False)
        user = request.user
        rinstance.owner = user
        rinstance.save()
        iinstance.owner = user
        cinstance.owner = user
        iinstance.recipe_id = rinstance.id
        cinstance.recipe_id = rinstance.id
        iinstance.save()
        cinstance.save()
        return HttpResponseRedirect('/admin/')
    context = {
        'rform' : rform,
        'iform' : iform,
        'cform' : cform,
    }
    return render(request, "add_new_recipe.html", context)

模板:add_new_recipe.html

<!DOCTYPE html>
<html>
<head>
    <title>Add Recipe</title>
</head>

<body>
    <div>
        <h1>Add Recipe</h1>
        <form action="" method="post">
            {% csrf_token %}
            <div>
                {{ rform.as_p }}
                {{ iform.as_p }}
                {{ cform.as_p }}
            </div>
            <input type="submit" value="Add recipe" class="submit" />
        </form>
    </div>
</body>
</html>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM