2017-10-17 50 views
7

Mam aplikację Django, którą chcę móc używać w wielu instancjach. Jeden model (listing) może mieć zmienną liczbę pól (dla różnych instancji), ale zawsze będzie miał dokładnie te dodatkowe pola dla instancji. Chcę te dodatkowe pola dodane przez administratora więc utworzone modele tak:Wyświetlaj nieznaną liczbę pól w szablonie Django z zawartością pola innego rekordu jako etykietę

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) 

Teoria jest admin określa zindywidualizowane pola i są następnie wyświetlane użytkownikowi w formach. W ciągu administratora jest to stosunkowo proste, jak można zakładać na odrobinę inteligencji od użytkowników tak mój admin.py wygląda następująco:

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

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

To znaczy, że użytkownik administrator musi wybrać jedną z każdym BespokeField z rozwijanego menu, ale nie jest to niewygodne, ponieważ używając unique_together upewnij się, że jest tylko jeden z nich.

Nie mogę się dowiedzieć, jak to zrobić, aby przedstawić to użytkownikowi nieadministracyjnemu w przyjazny sposób. To, czego chcę, to BespokeField.name do wyświetlenia w formularzu jako etykieta dla ListingBespokeField.value.

To jest to, co mam w forms.py (dla 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 
) 

jestem następnie próbuje przedstawić go przez matrycę, co następuje:

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

To nie działa. Mógłbym użyć trochę wglądu, proszę.

+0

Co to jest, że nie działa dokładnie? – Jonathan

+0

Potrzebuję go, aby wyświetlić nazwę Bespoke.name jako etykietę w formularzu dla listy, na której znajdują się pola dla Listing.ListingBespokeField. Obecnie pokazuje "Pole na zamówienie" – HenryM

+1

Czy możesz zapewnić dostęp do publicznego repozytorium? –

Odpowiedz

2

To było moje rozwiązanie:

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