I have a Django application that I want to use in multiple instances. One model (Listing) can have a variable number of fields (for different instances), but will always have exactly such additional fields for an instance. I want to add these additional fields via admin, so I created such models:
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)
The admin theory defines custom fields, and they are then displayed to the user in forms. Inside the admin, this is relatively simple, since I can accept modicum for intelligence from users, so my admin.py looks like this:
class ListingBespokeFieldInline(admin.TabularInline): model = ListingBespokeField extra = len(BespokeField.objects.all()) max_num = len(BespokeField.objects.all()) class ListingAdmin(admin.ModelAdmin): inlines = [ListingBespokeFieldInline]
This means that the admin user must select one of each BespokeField from the drop-down list, but I'm not uncomfortable, because using unique_together, make sure that there is only one of them.
The fact that I cannot understand how to do this presents this to a user without administrator privileges in a friendly manner. I want BespokeField.name appear on the form as a label for ListingBespokeField.value .
This is what I have in forms.py (for 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 )
Then I try to present it through a template as follows:
<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>
This does not work. I could use some understanding, please.