2010-07-19 75 views
6

我已經放在一起來保存配方。它使用了一個表單和一個內聯formset。我有用戶使用含有食譜的文本文件,他們希望剪切和粘貼數據以使輸入更容易。我已經計算出如何在處理原始文本輸入後填充表單部分,但我無法弄清楚如何填充內聯表單。Django Inline Formsets的初始數據

似乎這個解決方案几乎拼寫在這裏: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與配料:

  • 設置初始數據,但不用於在線表單集
  • 傳入一個字典工作,但其產生的管理形式錯誤
  • 打得四處初始化,但我有點不在我的深度有

不勝感激的任何建議。

回答

19

我的第一個建議是採取簡單的出路:保存RecipeRecipeIngredient s,則使得FormSet使用時所產生的Recipe爲您的實例。您可能需要將「已審覈」布爾字段添加到您的食譜中,以指示該表單集是否被用戶批准。

但是,如果你不希望走這條路不管什麼原因,你應該能夠來填充表單集是這樣的:

我們假設你已經分析的文本數據轉換成配方成分,並有一個像這樣的字典的列表:

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列表設置爲一本字典。它似乎對我來說顯示formset,但我還沒有嘗試保存。

+0

偉大的建議亞蘭,非常感謝你。我會在今天嘗試這些選項。我特別喜歡有一個簡單的選擇... – Sinidex 2010-07-19 14:16:26

+0

使用zip絕對的作品,我可以證實,以通常的方式保存表單也可以。正如你所指出的,我仍然需要將解析後的文本與相關的成分和度量單位相匹配,但我認爲這應該是可以管理的。好的解決方案 – Sinidex 2010-07-19 17:04:26

+1

是的,是的。這是一個很好的解決方案!我很難做到這一點。我首先研究如何構建集合中的每個表單。然後在一個表單(而不是formset)的基礎上實現了初始*做*工作。在zip中,我們相信™ – Flowpoke 2015-06-05 15:14:03

0

我不能讓亞蘭Dulyan代碼工作在這個

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

顯然對事情的Django 1.8改變了,我不能重複一個cached_property

形式 - django.utils.functional。在0x7efda9ef9080

cached_property對象,我得到這個錯誤

拉鍊參數#1必須支持迭代

但我還是拿字典,並直接分配到我的表單集和它的工作,我從這裏的例子:

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

from django.forms從myapp.forms導入formset_factory 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)}, 
]) 

我將代碼分配成模板到模板

return self.render_to_response(
self.get_context_data(form=form, inputvalue_numeric_formset=my_formset(initial=formset_dict)