我试图弄清楚如何用Django(1.6)形式弄清楚两件事。我希望使用ModelForm创建一个表单,其模型具有多个使用的ManyToManyField。我似乎可以弄清楚如何在表单中显示ManyToMany项目。
我想弄清楚的另一件事是如何拆分表格。例如,如果我想要一个看起来像这样的表单。
注意:配方模型的一部分(名称,说明)然后是ManyToManyField(水果和随之而来的项目。)然后是配方模型(Fruit_notes)中的另一个项目,然后是第二个ManyToManyField ......等
姓名:__________________说明:___________
水果:___________数量:_________
水果笔记:____________
蔬菜:___________数量:__________
veg说明:___________
models.py文件
from django.db import models
class Vegetable(models.Model):
name = models.CharField(max_length=150, blank=True)
description = models.TextField(blank=True)
def __unicode__(self):
return self.name
class Fruit(models.Model):
name = models.CharField(max_length=150, blank=True)
description = models.TextField(blank=True)
def __unicode__(self):
return self.name
class Recipe(models.Model):
name = models.CharField(max_length=450, blank=True)
description = models.TextField(blank=True)
fruits = models.ManyToManyField('Fruit', through='RecipeFruit')
fruit_notes = models.TextField(blank=True)
vegetables = models.ManyToManyField('Vegetable' through='RecipeVegetable')
Vegetables_notes = models.TextField()
class RecipeVegetable(models.Model):
recipe = models.ForeignKey(Recipe)
veg = models.ForeignKey(Vegetable)
qty = models.FloatField()
class RecipeFruit(models.Model):
recipe = models.ForeignKey(Recipe)
fruit = models.ForeignKey(Fruit)
qty = models.FloatField()
forms.py文件
from django import forms
from django.forms import ModelForm, Textarea
from django.forms.formsets import formset_factory
from models import Recipe, Vegetable, Fruit
from crispy_forms.helper import FormHelper
from crispy_forms.layout import Submit
class CreateRecipeForm(forms.ModelForm):
class Meta:
model = Recipe
def __init__(self, *args, **kwargs):
super(CreateRecipeForm, self).__init__(*args, **kwargs)
self.helper = FormHelper()
self.helper.form_id = 'id-RecipeForm'
self.helper.form_class = 'form-inline'
self.helper.form_method = 'post'
self.helper.form_action = 'submit_survey'
self.helper.add_input(Submit('submit', 'Submit'))
看起来朝着解决这个问题迈出了一大步,但我很难掌握如何引入两件物品。 (例如,水果和蔬菜)
如果有人能指出我正确的方向,并提供一个小例子,那将非常感激。在查看django文档时,我真的没有看到任何拼写出来的东西。
答案 0 :(得分:0)
前几天我和一对多关系工作,并且已经解决了这个问题(为了理解,我从我的源代码中修改了一些名称)。 我没有测试过你的例子,但它应该只需要很小的修改(如果需要),记住formset只能在ForeignKeys上工作,如果下面的波纹不起作用,请尝试使用model = Recipe.fruits.through或Recipe.vegetables.through 。 波纹管仅适用于一个内联formset,但您可以使用相同的方式添加其他formset:
# forms.py
class RecipeForm(forms.ModelForm):
...
class Meta:
model = Recipe
....
class FruitForm(forms.ModelForm):
...
class Meta:
model = RecipeFruit
...
RecipeFormSet = inlineformset_factory(Recipe, RecipeFruit, form=FruitForm, extra=1)
# views.py
class RecipeCreateView(CreateView):
form_class = RecipeForm
template_name = "recipes/recipe_add.html"
success_url = reverse_lazy('recipe-lists')
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)
recipe_formset = RecipeFormSet()
return self.render_to_response(
self.get_context_data(form=form,recipe_formset=recipe_formset))
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)
recipe_formset = RecipeFormSet(request.POST)
if (form.is_valid() and recipe_formset.is_valid()):
return self.form_valid(form, recipe_formset)
else:
return self.form_invalid(form, recipe_formset)
def form_valid(self, form, recipe_formset):
"""
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()
recipe_formset.instance = self.object
recipe_formset.save()
return super(RecipeCreateView, self).form_valid(form)
def form_invalid(self, form, recipe_formset):
"""
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,recipe_formset=recipe_formset))