我已经整理了一份表格以保存食谱。它使用表单和内联formset。我的用户使用包含食谱的文本文件,他们希望剪切和粘贴数据以使条目更容易。我已经研究了如何在处理原始文本输入后填充表单部分,但我无法弄清楚如何填充内联表单集。
似乎解决方案几乎在这里拼写出来:http://code.djangoproject.com/ticket/12213但是我不能把各个部分放在一起。
我的模特:
#models.py
from django.db import models
class Ingredient(models.Model):
title = models.CharField(max_length=100, unique=True)
class Meta:
ordering = ['title']
def __unicode__(self):
return self.title
def get_absolute_url(self):
return self.id
class Recipe(models.Model):
title = models.CharField(max_length=255)
description = models.TextField(blank=True)
directions = models.TextField()
class Meta:
ordering = ['title']
def __unicode__(self):
return self.id
def get_absolute_url(self):
return "/recipes/%s/" % self.id
class UnitOfMeasure(models.Model):
title = models.CharField(max_length=10, unique=True)
class Meta:
ordering = ['title']
def __unicode__(self):
return self.title
def get_absolute_url(self):
return self.id
class RecipeIngredient(models.Model):
quantity = models.DecimalField(max_digits=5, decimal_places=3)
unit_of_measure = models.ForeignKey(UnitOfMeasure)
ingredient = models.ForeignKey(Ingredient)
recipe = models.ForeignKey(Recipe)
def __unicode__(self):
return self.id
使用ModelForm:
创建配方表单class AddRecipeForm(ModelForm):
class Meta:
model = Recipe
extra = 0
视图中的相关代码(解析表单输入的调用被删除):
def raw_text(request):
if request.method == 'POST':
...
form_data = {'title': title,
'description': description,
'directions': directions,
}
form = AddRecipeForm(form_data)
#the count variable represents the number of RecipeIngredients
FormSet = inlineformset_factory(Recipe, RecipeIngredient,
extra=count, can_delete=False)
formset = FormSet()
return render_to_response('recipes/form_recipe.html', {
'form': form,
'formset': formset,
})
else:
pass
return render_to_response('recipes/form_raw_text.html', {})
如上所示,FormSet()为空,我可以成功启动页面。我已经尝试了几种方法来为formset提供我已经确定的数量,unit_of_measure和成分,包括:
任何建议都非常感谢。
答案 0 :(得分:20)
我的第一个建议是采取简单的方法:保存Recipe
和RecipeIngredient
,然后在生成Recipe
时使用生成的FormSet
作为您的实例。您可能希望在配方中添加“已审核”布尔字段,以指示表单集是否已被用户批准。
但是,如果你不想出于某种原因走这条路,你应该能够像这样填充你的表格集:
我们假设你已经将文本数据解析为配方成分,并且有一个像这样的词典列表:
recipe_ingredients = [
{
'ingredient': 2,
'quantity': 7,
'unit': 1
},
{
'ingredient': 3,
'quantity': 5,
'unit': 2
},
]
“成分”和“单位”字段中的数字是各个成分和度量对象单位的主键值。我假设您已经制定了一些方法来将文本与数据库中的成分相匹配,或者创建新的成分。
然后你可以这样做:
RecipeFormset = inlineformset_factory(
Recipe,
RecipeIngredient,
extra=len(recipe_ingredients),
can_delete=False)
formset = RecipeFormset()
for subform, data in zip(formset.forms, recipe_ingredients):
subform.initial = data
return render_to_response('recipes/form_recipe.html', {
'form': form,
'formset': formset,
})
这会将formset中每个表单的initial
属性设置为recipe_ingredients
列表中的字典。在显示formset方面似乎对我有用,但我还没有尝试过保存。
答案 1 :(得分:1)
我无法使Aram Dulyan代码适用于此
for subform, data in zip(formset.forms, recipe_ingredients):
subform.initial = data
显然django 1.8上发生了一些变化,我无法迭代cached_property
表格 - 位于0x7efda9ef9080的django.utils.functional.cached_property对象
我收到了这个错误
zip参数#1必须支持迭代
但是我仍然拿着字典并将它直接分配给我的formset并且它有效,我从这里拿了例子:
https://docs.djangoproject.com/en/dev/topics/forms/formsets/#understanding-the-managementform
来自django.forms import formset_factory 来自myapp.forms import ArticleForm
ArticleFormSet = formset_factory(ArticleForm, can_order=True)
formset = ArticleFormSet(initial=[
{'title': 'Article #1', 'pub_date': datetime.date(2008, 5, 10)},
{'title': 'Article #2', 'pub_date': datetime.date(2008, 5, 11)},
])
我的代码将formset分配给模板
return self.render_to_response(
self.get_context_data(form=form, inputvalue_numeric_formset=my_formset(initial=formset_dict)