derrend
derrend

Reputation: 4636

How to change form layouts in Django 1.8

I have a form

Field Name: [Input Box]

I want

Field Name:
[Input Box]

How can I achieve this?

forms.py

class SearchForm(forms.Form):
    search = forms.CharField()

views.py

form = SearchForm()
html_dtc = {'form':form}
return render_to_response('site/home.html', html_dtc)

home.html

<form method='POST' action=''> {% csrf_token %}
    {{ form.as_p }}
    <button type="submit" class="btn btn-success btn-sm">Update</button>
</form>

Thank you :)

Upvotes: 12

Views: 5378

Answers (6)

zinking
zinking

Reputation: 5695

generally I don't recommend use the HTML code generated by Django, but instead I supply what is needed by the DJANGO form.

but some are required: like the ERRORs, like the CSRF token.

let me add some examples to clarify what I am talking

<form class="*" style="*">
    <label /><input name="email" />
    <label /><input name="password" />
<form>

basically what I am suggesting is, do not use template tags unless absolute necessary like CSRF.

in this way, you can completely separate the design from the backend logic. you can have front end work indecently on the UI. the interface is the form fields, you have to supply all fields to the backend. like in this case 'email' && 'password' is required at backend

Upvotes: 1

Rizwan Mumtaz
Rizwan Mumtaz

Reputation: 3965

you can do

<form method='POST' action=''>
    {% csrf_token %}
    <label>Field Name:</label>
    {{ form.search }}
    <button type="submit" class="btn btn-success btn-sm">Update</button>
</form>

Upvotes: 1

Danial Tz
Danial Tz

Reputation: 1984

Use django_crispy_forms: http://django-crispy-forms.readthedocs.org/en/latest/

In the template include {% load crispy_forms_tags %} and for the form:

{% crispy form %}

In addition, you can change the layout of the form easily, by overriding the form_class in the init function of the form:

class ContactForm(forms.Form):
    def __init__(self, *args, **kwargs):
        super(ContactForm, self).__init__(*args, **kwargs)
        self.helper = FormHelper()
        self.helper.form_tag = False
        self.helper.form_class = 'form-horizontal' # <-- leave out for vertical, or form-inline
        self.helper.render_hidden_fields = True
        self.helper.layout = Layout(
            Div(InlineRadios('applying_for_whom'), css_class="col-xs-12"),
            Div(InlineRadios('gender'), css_class='col-xs-12'),
            Div('agreed_to_data_transmit', css_class="col-xs-12"),

As a bonus, if you are using bootstrap, set also set CRISPY_TEMPLATE_PACK = 'bootstrap3' so then everything is taken care of automatically for vertical bootstrap.

Upvotes: 1

Geo Jacob
Geo Jacob

Reputation: 6009

Try to overide form.as_p()

class SearchForm(forms.Form):
   search = forms.CharField()

   def as_p(self):
    "Returns this form rendered as HTML <p>s."
     return self._html_output(
        normal_row='<p%(html_class_attr)s>%(label)s <br> %(field)s%(help_text)s</p>',
        error_row='%s',
        row_ender='</p>',
        help_text_html=' <span class="helptext">%s</span>',
        errors_on_separate_row=True)

Upvotes: 3

zanderle
zanderle

Reputation: 825

You want a custom form rendering. You can read more about it here. For example, the following code would achieve what you're after.

<form method='POST' action=''> {% csrf_token %}
    {% for field in form %}
    <div class="fieldWrapper">
        {{ field.errors }}
        {{ field.label_tag }} <br/>
        {{ field }}
    </div>
    {% endfor %}
    <button type="submit" class="btn btn-success btn-sm">Update</button>
</form>

(field.errors are added, because when you are manually rendering the form, you have to take care of error rendering as well)

Upvotes: 10

Christine Sch&#228;pers
Christine Sch&#228;pers

Reputation: 1318

If this is a one off thing you can render your form manually like described here in the documentation.

Otherwise there's the django-floppyforms which gives you great control over how forms and (default) widgets are rendered. Just define a custom layout, make it the default, use floppyforms custom Form classes (they behave exactly the same) and you're good to go.

As far as I remember some of floppyforms's functionality will also be included in Django 1.9, so look out for that, too.

Upvotes: 2

Related Questions