11

我已经整理了一个表格来保存食谱。它使用表单和内联表单集。我的用户拥有包含食谱的文本文件,他们希望剪切和粘贴数据以使输入更容易。我已经弄清楚如何在处理原始文本输入后填充表单部分,但我无法弄清楚如何填充内联表单集。

似乎解决方案几乎在这里说明了: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() 为空,我可以成功启动页面。我尝试了几种方法来为表单集提供我确定的数量、unit_of_measure 和成分,包括:

  • 设置初始数据,但这不适用于内联表单集
  • 传递字典,但会产生管理表单错误
  • 玩过init,但我在那里有点超出我的深度

任何建议都非常感谢。

4

2 回答 2

23

我的第一个建议是采取简单的方法:保存Recipeand RecipeIngredients,然后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,
     })

这会将表单集中initial每个表单的属性设置为recipe_ingredients列表中的字典。就显示表单集而言,它似乎对我有用,但我还没有尝试保存。

于 2010-07-19T11:27:15.337 回答
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 必须支持迭代

但是我仍然拿着字典并将其直接分配给我的表单集并且它起作用了,我从这里举了一个例子:

https://docs.djangoproject.com/en/dev/topics/forms/formsets/#understanding-the-managementform

从 django.forms 导入 formset_factory 从 myapp.forms 导入 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)},
])

我将表单集分配给模板的代码

return self.render_to_response(
self.get_context_data(form=form, inputvalue_numeric_formset=my_formset(initial=formset_dict)
于 2016-01-30T14:10:20.307 回答