2016-11-08 2 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() 

내가 장고 BaseInlineFormSet를 사용하여 제안 알고 있지만, 대부분의 사람들이 views.py와 사용자가 아닌 필드를 절약 제안 자동하지만 멋지게

ingredient_form.owner= self.request.user 

저장 양식 또는 모델을 만들 수 있습니다. 나는 어떤 제안이나 대답을 주셔서 감사합니다. 좀 더 많은 연구와 솔루션은 다소 복잡한 모양 않았다

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

models.py : 여기에 전체 코드입니다 custom formset saving을 추가하는 방법에 대한이 가이드를 따르면 BaseInlineFormset으로 수정되었습니다. 위의 ed. 새로운 레서피보기를 추가 할 때 한 번에 하나의 하위 양식 만 필요하고 ModelForm 코드를 다시 사용할 수 있기 때문에 각 모델에 대한 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> 
관련 문제