I have a model:
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()
I would like to create a form that looks something like:
<form method="POST" action=""> {% for model in models %} <label>{{model.name}}</label> <input value='{{model.value}}' /> <p>{{model.description}}</p> {% endfor %} </form>
I'm not quite sure how to go about doing this. Perhaps I need to use a 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, {}))
Then in the template, I'd want to render the form differently than default. I'm not quite sure how to go about accessing the model properties, however. Is this the right approach, or is there another way I should be going about doing this?
Update: This is what I'm currently doing. It renders exactly as I'd like it to, aside from the styling. However, I feel that it's deeply 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 %}
Is there a better approach to this?
Also, I'm not sure if I'll encounter problems when the form is submitted or not.
Create a custom template tagUnder the application directory, create the templatetags package (it should contain the __init__.py file). For example, Django/DjangoApp/templatetags. In the templatetags package, create a . py file, for example my_custom_tags, and add some code to it to declare a custom tag.
To configure the Django template system, go to the settings.py file and update the DIRS to the path of the templates folder. Generally, the templates folder is created and kept in the sample directory where manage.py lives. This templates folder contains all the templates you will create in different Django Apps.
<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>
You can find the complete documentation here: http://docs.djangoproject.com/en/dev/topics/forms/#customizing-the-form-template
I don't think you need a formset here. Take a look here if you want a custom template for one view. If you want to create your own {{ form.as_foobar }}, just subclass forms.Form, something like this:
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)
and just use it in your forms.py:
class ContactForm(MyForm): # ..
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With