2016-11-08 67 views
-1

我一直在使用這個好帖子http://kevindias.com/writing/django-class-based-views-multiple-inline-formsets/來設置我的網站。我想知道如何將用戶字段自動保存到視圖中的內聯formset(我使用blockquote來更改原始內容)。在RecipeForm(另見下文的情況下)如何使用視圖在Django中保存內聯formset用戶字段

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

forms.py

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

回答

0

我做了一些更多的研究和解決方案看起來有些複雜按照本指南如何添加custom formset saving但修改爲BaseInlineFormset提及以上所述。我意識到爲每個模型製作ModelForms並將它們鏈接到一個視圖中會更簡單,因爲我一次只需要添加一個子表單並添加一個新的配方視圖,並且可以重新使用ModelForm代碼。

這裏有一個很好的新代碼!如果您需要更多信息,請隨時聯繫。

forms.py

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> 
相關問題