我有一个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指定定制字段,然后以表格形式显示给用户。在管理员中这是相对简单的,因为我可以假设用户的智能,所以我的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]
这确实意味着管理员用户必须从下拉列表中选择每个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 :(得分: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>