首页 文章

Django内联表单集的初始数据

提问于
浏览
7

我已经整理了一个表格以保存食谱 . 它使用表单和内联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()为空,我可以成功启动页面 . 我已经尝试了几种方法来提供我确定的数量,unit_of_measure和成分,包括:

  • 设置初始数据,但不适用于内联表单集

  • 传递字典,但会产生管理表单错误

  • 玩了 init ,但我有点超出我的深度

任何建议都非常感谢 .

2 回答

  • 20

    我的第一个建议是采取简单的方法:保存 RecipeRecipeIngredient ,然后在制作 FormSet 时使用生成的 Recipe 作为您的实例 . 您可能希望在配方中添加"reviewed"布尔字段,以指示表单集是否已被用户批准 .

    但是,如果您不想出于某种原因走这条路,您应该能够填充这样的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

    我不能让Aram Dulyan代码在这方面起作用

    for subform, data in zip(formset.forms, recipe_ingredients):
        subform.initial = data
    

    显然在django 1.8上发生了一些变化,我无法迭代cached_property

    forms - 位于0x7efda9ef9080的django.utils.functional.cached_property对象

    我收到了这个错误

    zip参数#1必须支持迭代

    但是我仍然拿着字典并将它直接分配给我的formset并且它有效,我从这里拿了例子:

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

    来自myj.forms导入ArticleForm的django.forms import formset_factory

    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)
    

相关问题