2017-10-17 11 views
7

J'ai une application Django que je veux pouvoir utiliser dans plusieurs instances. Un modèle (Listing) peut avoir un nombre variable de champs (pour les différentes instances) mais aura toujours exactement ces champs supplémentaires pour l'instance. Je veux que ces champs supplémentaires ajoutés par admin J'ai donc créé des modèles comme celui-ci:Afficher un nombre inconnu de champs dans le modèle Django avec le contenu du champ d'un autre enregistrement comme étiquette

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) 

La théorie est admin spécifie les champs sur mesure et ceux-ci sont alors affichées à l'utilisateur dans les formulaires. Au sein de cette administration est relativement simple que je peux prendre un minimum sur l'intelligence des utilisateurs pour mon admin.py ressemble à:

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

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

Cela ne signifie que l'utilisateur admin doit choisir un de chaque BespokeField dans le menu déroulant, mais je Je ne suis pas mal à l'aise avec ça parce qu'en utilisant unique_together, il n'y en a qu'un seul.

Ce que je ne parviens pas à faire est de présenter ceci à l'utilisateur non-administrateur de manière amicale. Ce que je veux, c'est le BespokeField.name à afficher sur le formulaire comme une étiquette pour ListingBespokeField.value. C'est ce que j'ai dans forms.py (pour 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 
) 

Je puis essayer de le présenter à travers un modèle comme suit:

<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> 

Cela ne fonctionne pas. Je pourrais utiliser un aperçu s'il vous plaît.

+0

Qu'est-ce qui ne fonctionne pas exactement? – Jonathan

+0

J'en ai besoin pour montrer le BespokeField.name comme label dans un formulaire pour Listing où j'ai les champs pour Listing.ListingBespokeField. Actuellement, il affiche 'Champ sur mesure' – HenryM

+1

Pourriez-vous donner accès à un dépôt public? –

Répondre

2

C'était ma solution:

<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>