2017-10-17 37 views
7

我有一个Django应用程序,我希望能够在多个实例中使用它。一个模型(列表)可以具有可变数量的字段(针对不同的实例),但是将始终具有该实例的那些额外字段。我想通过管理员添加所以我创建的模型这样这些额外的字段:显示Django模板中字段内容为另一个记录的未知数量的字段作为标签

class BespokeField (models.Model): 
    name = models.CharField(
     max_length = 20, 
     verbose_name = "Field Title" 
    ) 

    def __unicode__(self): 
     return self.name 

class Listing (models.Model): 
    name = models.CharField (
     verbose_name = 'Listing', 
     max_length = 30 
    ) 
    slug = models.SlugField (
     verbose_name = "Slug", 
     allow_unicode = True, 
     unique=True, 
     blank=True, 
     null=True 
    ) 

class ListingBespokeField (models.Model): 
    bespoke_field = models.ForeignKey(BespokeField) 
    listing = models.ForeignKey(Listing) 
    value = models.CharField (
     max_length = 60 
    ) 

    def __unicode__(self): 
     return u'%s | %s' % (self.listing.name, self.bespoke_field.name) 

理论是管理员指定定制字段,然后它们显示在表格的用户。在管理这个比较简单,因为我可以从用户承担智力上一点点,所以我的admin.py的样子:

class ListingBespokeFieldInline(admin.TabularInline): 
    model = ListingBespokeField 
    extra = len(BespokeField.objects.all()) 
    max_num = len(BespokeField.objects.all()) 

class ListingAdmin(admin.ModelAdmin): 
    inlines = [ListingBespokeFieldInline] 

它意味着admin用户必须从下拉菜单中选择每个BespokeField之一,但我这并不令人不舒服,因为通过使用unique_together确保只有一个。

我不能解决的方法是以友好的方式将其呈现给非管理员用户。我想要的是BespokeField.name作为ListingBespokeField.value的标签在窗体上显示。

这就是我在forms.py(对于ListingBespokeField)。

class ListingBespokeFieldInline(forms.ModelForm): 
    class Meta: 
     model = ListingBespokeField 
     exclude =['id'] 
     widgets = { 
      'bespoke_field' : forms.HiddenInput(), 
      'value' : forms.TextInput(attrs={'class' : 'form-control'}) 
     } 

class ListingBespokeFieldForm(forms.ModelForm): 
    class Meta: 
     model = ListingBespokeField 
     exclude =() 

BESPOKE_FIELD_COUNT = len(BespokeField.objects.all()) 

ListingBespokeFieldInlineFormSet = forms.inlineformset_factory (
    Listing, 
    ListingBespokeField, 
    form=ListingBespokeFieldInline, 
    extra = BESPOKE_FIELD_COUNT, 
    max_num = BESPOKE_FIELD_COUNT, 
    exclude = ['id'], 
    can_delete=False, 
    can_order=False 
) 

我则试图通过模板如下呈现它:

<table class="table"> 
    {{ bespokefields.management_form }} 

    {% for form in bespokefields.forms %} 
     {% if forloop.first %} 
     <thead> 
      <tr> 
       {% for field in form.visible_fields %} 
        <th>{{ field.label|capfirst }}</th> 
       {% endfor %} 
      </tr> 
     </thead> 
     {% endif %} 
     <tr class="formset_row bespokefield"> 
      <td> 
       {{ form.listing }}{{ form.id }}{{ form.bespoke_field }} 
       {{ form.bespoke_field.label }} 
      </td> 
      <td>{{ form.value }}</td> 
     </tr> 
    {% endfor %} 
</table> 

这是行不通的。我可以使用一些见解。

+0

它是什么,不完全工作? – Jonathan

+0

我需要它将BespokeField.name显示为列表中的标签,其中列出了Listing.ListingBespokeField的字段。目前,它显示'定制字段' – HenryM

+1

您可以提供对公共存储库的访问吗? –

回答

2

这是我的解决方案:

<table class="table"> 
    {{ bespokefields.management_form }} 

    {% for form in bespokefields.forms %} 
     <tr class="formset_row bespokefield"> 
      <td> 
       {{ form.listing }}{{ form.id }} 
       <select id="id_listingbespokefield_set-{{ forloop.counter0 }}-bespoke_field" name="listingbespokefield_set-{{ forloop.counter0 }}-bespoke_field" class="form-control"> 
       {% with forloop.counter as counter %} 
        {% for x,y in form.fields.bespoke_field.choices %} 
         {% if counter == forloop.counter0 %} 
          <option value="{{x}}" selected>{{y}}</option> 
         {% endif %} 
        {% endfor %} 
       {% endwith %} 
       </select> 
      </td> 
      <td>{{ form.value }}</td> 
     </tr> 
    {% endfor %} 
</table> 
相关问题