2011-02-04 19 views
17

Mam model:Django: Jak utworzyć formularz z niestandardowym szablonem?

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

Chciałbym utworzyć formularz, który wygląda mniej więcej tak:

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

nie jestem pewien, jak go o to robi. Być może muszę użyć zestawu?

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, {})) 

Następnie w szablonie chciałbym renderować formularz inaczej niż domyślnie. Nie jestem jednak całkiem pewien, jak uzyskać dostęp do właściwości modelu. Czy to właściwe podejście, czy jest inny sposób, w jaki powinienem to zrobić?

Aktualizacja: Właśnie to robię obecnie. Wykonuje się dokładnie tak, jak bym chciał, poza stylem. Jednak czuję, że to głęboko 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 %} 

Czy istnieje lepsze podejście do tego?

Ponadto nie jestem pewien, czy napotkam problemy podczas przesyłania formularza.

Odpowiedz

9

Nie sądzę, że potrzebujesz tutaj formularza. Spójrz na here, jeśli chcesz niestandardowy szablon dla jednego widoku. Jeśli chcesz stworzyć swój własny {{form.as_foobar}}, tylko podklasy forms.Form, coś takiego:

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) 

i po prostu używać go w forms.py:

class ContactForm(MyForm): 
    # .. 
+0

A jak dostanę wyniki 'as_foobar' w szablon? –

+0

To również określa dane wyjściowe na poziomie pola, prawda? Potrzebuję: "Model.name.value: Model.value.value (Model.description.value)" –

+1

Używałbyś {{form.as_foobar}} (podobnie jak form.as_p) w szablonie. Zastąp "formularz" dowolną zmienną formularza. –

1

Looks tak jakbyś był zainteresowany django-floppyforms (docs), co daje znacznie większą kontrolę nad renderowaniem pola.

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

można znaleźć pełną dokumentację tutaj: http://docs.djangoproject.com/en/dev/topics/forms/#customizing-the-form-template

+1

Również nie widzę do momentu użycia formsets. Robi się coś takiego: podobnie jak: \t z django.Formy importować ModelForm \t klasy IntegerSettingForm (ModelForm): \t \t class Meta: \t \t \t Model = IntegerSetting należy utworzyć klasę IntegerSettingForm, które można wykorzystać do tworzyć instancje formularzy w widokach. – SashaN

+0

Powoduje wydrukowanie wszystkich pól, ale chcę użyć wartości jednego pola jako etykiety i tylko jedno pole może być faktycznie wejściem. –

+0

Załączona dokumentacja była przydatna, ale nie podano atrybutu pola do wydrukowania wartości, a nie widżetu. Tego naprawdę chcę. –

3

Bo kto potrzebuje wersję jbcurtin za odpowiedź <table>:

<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> 
Powiązane problemy