Django: Come fare un form con custom template?

Ho un modello:

class Setting(models.Model):

    class Meta:
        abstract = True

    name = models.CharField(max_length=120, primary_key=True)
    description = models.CharField(max_length=300, blank=True)

class IntegerSetting(Setting):
    value = models.IntegerField()

Vorrei creare un modulo che sembra qualcosa di simile:

<form method="POST" action="">
     {% for model in models %}
     <label>{{model.name}}</label> <input value='{{model.value}}' />
     <p>{{model.description}}</p>
     {% endfor %}
</form>

Io non sono del tutto sicuri di come fare questo. Forse ho bisogno di utilizzare un formset?

from django.forms.models import modelformset_factory
from apps.about.models import Setting, IntegerSetting

def site_settings(request):
    formset = modelformset_factory(IntegerSetting)()

    return render_to_response("about/admin/site-settings.html", {'formset': formset}, RequestContext(request, {}))

Quindi nel modello, voglio rendere il form in modo diverso da quello predefinito. Io non sono molto sicuro di come andare su come accedere alle proprietà del modello, tuttavia. È questo l’approccio giusto, o c’è un altro modo dovrebbe essere facendo questo?

Aggiornamento: Questo è quello che sto facendo attualmente. Rende esattamente come mi piacerebbe che, a parte lo stile. Tuttavia, sento che è profondamente hacky:

class SettingsForm(ModelForm):
    class Meta:
        model = IntegerSetting

    def as_table(self):
        bound_field = BoundField(self, self.fields['value'], 'value')
        return mark_safe("<tr><td><label>%s</label></td><td>%s\n<p class='help'>%s</p></td></tr>" % (self.instance.name,
                                                                       self.instance.description, 
                                                                       bound_field.__unicode__())) 

def edit_settings(request):
    forms = [SettingsForm(instance=intSetting) for intSetting in IntegerSetting.objects.all()]

    return render_to_response("admin/edit-settings.html", {'forms': forms}, RequestContext(request, {}))

edit-settings.html:

{% extends "admin/base_site.html" %}
{% block title %}System Settings{% endblock %}

{% block content %}
    <form method="post" action="">
        <table>
        {% for form in forms %}
        {{form}}
        {% endfor %}
        </table>
    </form>
{% endblock %}

C’è un approccio migliore di questo?

Inoltre, non so se mi incontrano problemi quando il modulo viene inviato o non.

InformationsquelleAutor Nick Heiner | 2011-02-04



4 Replies
  1. 19
    <form action="/contact/" method="post">
        {% for field in form %}
            <div class="fieldWrapper">
                {{ field.errors }}
                {{ field.label_tag }}: {{ field }}
            </div>
        {% endfor %}
        <p><input type="submit" value="Send message" /></p>
    </form>

    È possibile trovare la documentazione completa qui:
    http://docs.djangoproject.com/en/dev/topics/forms/#customizing-the-form-template

    • Anche io non vedo il punto di usare i dati. Fare qualcosa di simile a questo: da django.i moduli di importazione di ModelForm classe IntegerSettingForm(ModelForm): classe di Meta: modello = IntegerSetting dovrebbe creare un IntegerSettingForm classe, che è possibile utilizzare per creare le istanze di modulo in vista.
    • Questo consente di stampare tutti i campi, ma voglio usare il valore di un campo come un’etichetta, e solo un campo effettivamente essere un input.
    • La documentazione allegata è stata utile, ma non ha fatto menzione di un attributo di campo per stampare il valore, non il widget. Che è quello che voglio davvero.
    • Se non si desidera che il valore sia modificabile, è possibile impostare ‘modificabile’ false sul modello e la forma del campo di pick-up su questo.
  2. 9

    Non credo che avete bisogno di un formset qui. Date un’occhiata qui se si desidera un modello personalizzato per una vista. Se si desidera creare il proprio {{ form.as_foobar }}, appena sottoclasse forme.Forma, qualcosa di simile a questo:

    class MyForm(forms.Form):
      def as_foobar(self):
        return self._html_output(
          normal_row = u'%(label)s %(field)s%(help_text)s',
          error_row = u'%s',
          row_ender = '',
          help_text_html = u' %s',
          errors_on_separate_row = False)

    e utilizzarlo nella vostra forms.py:

    class ContactForm(MyForm):
      # ..
    • E come faccio a ottenere i risultati di as_foobar nel modello?
    • Inoltre, questo è specificare l’output su un campo di livello, giusto? Ciò di cui ho bisogno è: “il Modello.nome.valore: Modello.valore.valore (Modello.descrizione.valore)”
    • Devi utilizzare {{ form.as_foobar }} (simile alla forma.as_p) nel modello. Sostituire la ‘forma’ con qualunque sia la vostra forma variabile è chiamato.
  3. 3

    Per coloro che necessitano di <table> versione di jbcurtin risposta:

    <form method="post">{% csrf_token %}
      <table>
        {% for field in form %}
          <tr>
            <th>{{field.label_tag}}</th>
            <td>
              {{ field.errors }}
              {{ field }}
            </td>
          </tr>
        {% endfor %}
      </table>
      <hr/>
      <input type="submit" value="Conferma" />
    </form>

Lascia un commento