2015-11-22 136 views
0

關於此的大多數問題似乎都集中在節省m2m表。我很好奇如何從一個(或兩個組合)表單中查看中間表的字段。Django:以表格的形式顯示中間表的字段

這個想法是我有很多資源和很多餐。不同的膳食可以有相同的資源,但數量不同。說:捲餅有x磅牛肉,但法加它有y。

我想要創建一個表單來編輯捲餅餐,以便我可以查看/編輯/創建:餐的名稱,餐中的資源以及與該餐中資源相關的數量。我當前的代碼顯示一個包含所有形式,但通過M2M表與資源相關的金額

我通過中介表連接的兩個車型:

class Resource(models.Model): 
    name = models.CharField(max_length=200) 
    unit = models.ForeignKey(Unit) 
    units_per_pack = models.PositiveSmallIntegerField() 
    packs_per_case = models.PositiveSmallIntegerField() 
    allergens = models.ManyToManyField(Allergen, blank=True) 

class Meal(models.Model): 
    name = models.CharField(max_length=200) 
    resources=models.ManyToManyField(Resource,through='MealResourceRelationship') 
    recipe = models.TextField(default='') 

class MealResourceRelationship(models.Model): 
    resource = models.ForeignKey(Resource) 
    meal = models.ForeignKey(Meal) 
    units_per_person = models.DecimalField(max_digits=19,decimal_places=2) 

我試圖用一個簡單的ModelForm作爲下方觀察:

class MealForm(forms.ModelForm): 
    class Meta: 
    model = Meal 
    fields = '__all__' 

這種觀點:

def meal_edit(request, pk=None, template_name='foodstuffs/meal_edit.html'): 
    if id: 
     meal = get_object_or_404(Meal, pk=pk) 
    else: 
     meal = Meal() 
    if request.POST: 
     form = MealForm(request.POST,instance=meal) 
     if form.is_valid(): 
      meal_mod = form.save(commit=False) 
      meal_mod.save() 

      # remove existing resources                                          
      meal_mod.resources.clear() 
      for resource in form.cleaned_data.get('resources'): 
       meal_resource_rel = MealResourceRelationship(meal=meal_mod, 
                  resource=resource, 
                  units_per_person=1) 
       meal_resource_rel.save() 
      # messages.add_message(request, messages.SUCCESS, _('Meal correctly saved.'))                              
      # If the save was successful, redirect to another page                                   
      redirect_url = reverse('meal_list') 
      return HttpResponseRedirect(redirect_url) 
    else: 
     form = MealForm(instance=meal) 

    args = {} 
    args.update(csrf(request)) 
    args['form'] = form 
    args['meal'] = meal 
    return render_to_response(template_name, args) 

不限想法?謝謝!

回答

0

基礎上Django的報價(短的完全自定義的形式),我認爲這是最簡單的看待這個問題兩個部分的解決方案:

  1. 如何爲所有可在MealResourceRelationships的提供形式與給定餐
  2. 如何顯示從1號的形式旁邊的形式爲膳食本身

答案1點在於Formsets,它允許多個窗體被渲染起來。對於您的特定情況,您希望將這些實例綁定到父對象(膳食),您對Inline Formsets感興趣,它允許您呈現與外鍵相關的多個表單實例。 查看此post瞭解如何通過關係使用內嵌式表單集w/m2m。

對於第2部分),您只需將原始表單和內聯表單呈現到同一頁面即可。一個例子見post

在此基礎上,你可以按以下步驟更新您的看法:

def meal_edit(request, pk=None, template_name='foodstuffs/meal_edit.html'): 
    # ADDED: Created an inline formset factory for the meal resource relationship 
    MealResourceFormset = forms.inlineformset_factory(Meal, Meal.resources.through, exclude=[]) 

    if id: 
     meal = get_object_or_404(Meal, pk=pk) 
    else: 
     meal = Meal() 

    if request.POST: 
     form = MealForm(request.POST, instance=meal) 
     if form.is_valid(): 
      meal_mod = form.save(commit=False) 
      meal_mod.save() 

      # remove existing resources                
      meal_mod.resources.clear() 
      for resource in form.cleaned_data.get('resources'): 
       meal_resource_rel = MealResourceRelationship(meal=meal_mod, 
                 resource=resource, 
                 units_per_person=1) 
       meal_resource_rel.save() 
      # messages.add_message(request, messages.SUCCESS, _('Meal correctly saved.'))    
      # If the save was successful, redirect to another page         
      redirect_url = reverse('meal_list') 
      return HttpResponseRedirect(redirect_url) 
    else: 
     # ADDED/EDITED: create both the meal form and resource formsets 
     meal_form = MealForm(instance=meal) 
     resource_formset = MealResourceFormset(instance=meal)               

    args = {} 
    args.update(csrf(request)) 
    args['form'] = meal_form 
    # ADDED: pass through resource_formset to template 
    args['formset'] = resource_formset 
    args['meal'] = meal 
    return render_to_response(template_name, args) 

您還需要更新您的模板來渲染表單集,既然你都使其更新MealForm不使資源領域(通過formset)。您可以通過編輯每個表格來進一步自定義每個部分。

希望這有助於作爲首發和你的項目好運!

相關問題