Producing the right HTML semantics with Django - django

I usually keep it simple and use the following form syntax in my templates:
<div>
<div>{{form.title.label}}:</div>
<div>{{form.title}}</div>
</div>
The problem with this approach is the bad semantic in the html output.
<div>
<div>Title:</div>
<div><input id="id_form-title" type="text" maxlength="30" name="form-title"></div>
</div>
Correct should be:
<div>
<label for="id_form-title">Title</label>
<input id="id_form-title" type="text" maxlength="30" name="form-title">
</div>
Is there a django build-in tag to do this automatically for me, or do I have to do it manually myself like this?
<div>
<label for="id_form-title">{{form.title.label}}</label>
{{form.title}}
</div>

It is indeed annoying that outputting fields one by one doesn't give you automatic access to a properly-constructed label element - doing form.as_p will correctly produce the fields plus labels, but you give up all control over the form layout.
You can build up the label tag using the field information fairly easily though:
<label for="{{ field.auto_id }}">{{ field.label }}</label>
{{ field }}
You can put this in a template tag for easier reuse.
Don't forget to also add {{ field.errors }} to display the errors associated with each field.

using label_tag should give you properly constructed label tag. So instead of just {{form.title.label}} you should use {{form.title.label_tag}} and it will result in the desired html

Related

customise django widget in template

I have standard model form in django with Imagefield and standard widget. It made me such output on the page:
Currently: qwe/Tulips.jpg <input id="image-clear_id" name="image-clear" type="checkbox" /> <label for="image-clear_id">Clear</label><br />
Change: <input id="id_image" name="image" type="file" />
I want to place outputs of this widget in different parts of page. How can I cut it in templates.
If there is a way to use part of the output in template like {{form.name_of_field.label}} or {{form.name_of_field.errors}}
I've tried different names but no use
There must be a way to use them apart.
And yet another one who needs form styling.
I would recommend to use Widget Tweaks
<form method='POST' action="/" enctype='multipart/form-data'>
{% load widget_tweaks %}
{% csrf_token %}
{{ form.first_name |add_class:"customCSS1 customCSS2" }}
{{ form.second_name |add_class:"customCSS3 customCSS4" }}
</form>
{{ form.media.js }}
with this plugin you can style the form as you wish. All Css classes work. You can put each form field wherever you want on the Page. Is that what you are looking for? Your question is a bit misleading.
Hope that helps if not leave a comment :)

How to individually call a form to a html in django?

First time creating a webapp in django. please bear with me.
So I have this code in my html:
<h1><font color="Orange" face="Borda">{{ template_title }}</h1>
<form method='POST' action=''>{% csrf_token %}
<font color="Orange" face="Borda" style="background-color: transparent;">{{ form }}</font>>
<input type='submit' value='SUBMIT'>
</form>
now inside {{ form }} is all the views and forms. now what I want to do is to specifically call it individually (with style).
for example if I have:
email=CharField()
username=CharField()
and I wanted to call them in my html as:
<label class="sr-only" for="r-form-first-name">**EMAIL/USERNAME**</label>
<input type="text" name="r-form-first-name" placeholder="First name..." class="r-form-first-name form-control" id="r-form-first-name">
How do I do that? I already have a bootstrap template prepared for my login but other documentation suggest I use crispy forms, which I dont want to. Please tell me how if there is other ways of calling it.
Since it's your first time building a django app, i suggest you take your time building it, try reading relative doc pages for the parts you're working with.
Here's an example from the docs (tailored for your case):
<div class="fieldWrapper">
{{ form.username.errors }}
<label for="{{ form.username.id_for_label }}">Your message:</label>
{{ form.username }}
</div>
https://docs.djangoproject.com/en/1.10/topics/forms/#rendering-fields-manually

g:render tag renders body() as plain text

I'm trying to render the template in GSP page
template:
<div class="container">
${body()}
</div>
template call:
<g:render template="/shared/wrapperTemplate">
<g:textField name="${property}" value="${value}" id="${property}id" class="form-control"/>
</g:render>
The body() is evaluated correctly and renders
<input type="text" name="name" value="" id="nameid" class="form-control" />
but when passing it to the template, it is surrounded by the quotes and instead of displaying input field, it prints the html input as string to the html page
I also tried with write TagLib
def fieldTemplate = { attrs, body ->
out << render(template: "/shared/wrapperTemplate", model: [content: body()])
}
But the result was the same (of course I had to change the tag call)
The idea was to reuse the formatting part of the template <div> for all _wrapper.gsp templates in Fields plugin, but not copy paste it. The case above is simplified, but I use Twitter Bootstrap and there is a bunch of lines that I don't want to copy.
_fields/default/_wrapper.gsp:
<div class="form-group ${hasErrors(bean:bean,field:property,'has-error')}">
<label for="${property}id" class="col-sm-2 control-label">${label}</label>
<div class="col-sm-10">
<g:textField name="${property}" value="${value}" id="${property}id" class="form-control" />
</div>
</div>
_fields/date/_wrapper.gsp:
<div class="form-group ${hasErrors(bean:bean,field:property,'has-error')}">
<label for="${property}id" class="col-sm-2 control-label">${label}</label>
<div class="col-sm-10">
<g:datePicker name="${property}" value="${value}" precision="day" id="${property}id" class="form-control" />
</div>
</div>
I am not able to understand the following lines of your post
but when passing it to the template, it is surrounded by the quotes
and instead of displaying input field, it prints the html input as
string to the html page
What is it in this case, please share the exact code which is not working.
The first example you shared is working for you, in the second example you passed content as parameter. When you are passing the parament then you need to change your code from
${body()}
to
${raw(content)}
I am still not sure what is the exact code which not working, just a wild guess.

Manually rendering subfields of a MultiValueField

In my Django 1.7 app, I'm trying to take advantage of the MultiValueField class to implement a password/confirm password form element, i.e. two separate password fields asking the user to enter and then confirm a new password. I already got this working with two separate fields and a clean() method on my form, but the "single" MultiValueField seems a better way of upholding the DRY principle, especially since I'll need to duplicate this not only in my user registration form, but also when users want to change their passwords.
However, my front-end is pretty specific, and not the least bit like Django's default form output, so I'm manually rendering my form fields. This works great -- until I get to the MultiValueField. For each form field, my HTML looks like this:
<div class="row collapse">
<div class="small-2 columns">
<span class="prefix"><i class="fi-mail"></i></span>
</div>
<div class="small-10 columns {% if form.email.errors %}error{% endif %}">
{{ form.email }}
{% if form.email.errors %}<small class="error">{{ form.email.errors }}</small>{% endif %}
</div>
</div>
I need to do similar formatting for each of the subfields of form.password, but nothing I've tried has given me a rendered subfield; the closest I've come is {{ form.fields.password.fields.0 }} in my template, which gives me output like <app.fields.PassField object at 0x7fb619821ef0>, however this obviously isn't a rendered form field.
Is there something simple and obvious that I'm missing, or is what I'm trying to do just not possible in Django?
The code in Render only one part of a MultiWidget in Django is appropriate for your problem, as farthVader suggests.
I had a similar problem and I ended up solving it this way:
<input type="text" id="{{ form.password.html_name }}_0" name="{{ form.password.html_name }}_0" value="{{ form.password.value.0|default_if_none:'' }}"/>
<input type="text" id="{{ form.password.html_name }}_1" name="{{ form.password.html_name }}_1" value="{{ form.password.value.1|default_if_none:'' }}"/>

Adding extra HTML tags and attributes to Django crispy-forms fields

I'm using django-crispy-forms with Bootstrap and I'm wanting to add some extra HTML inside the HTML rendered for the a single field.
For example if my form contains,
recipients = forms.CharField(label='To',widget=forms.TextInput(
attrs={'placeholder': 'Enter phone number, contact or group (add as many as you like)'}))
Then the normal rendering (using the Bootstrap templates) is,
<div id="div_id_recipients" class="control-group">
<label for="id_recipients" class="control-label requiredField">
To<span class="asteriskField">*</span>
</label>
<div class="controls">
<input class="textinput textInput" id="id_recipients" name="recipients" placeholder="Enter phone number, contact or group (add as many as you like)" type="text">
</div>
</div>
What I want to do is have some extra HTML appear just before the final closing div. So it would look like,
<div id="div_id_recipients" class="control-group">
<label for="id_recipients" class="control-label requiredField">
To<span class="asteriskField">*</span>
</label>
<div class="controls">
<input class="textinput textInput" id="id_recipients" name="recipients" placeholder="Enter phone number, contact or group (add as many as you like)" type="text">
</div>
<div class="controls-aside">
<button type="button" class="btn">Address Book</button>
<button type="button" class="btn">Add Contact</button>
</div>
</div>
I know that I can replace the existing template for this field with a custom template but I want to be able to re-use their template without doing a copy/paste since that makes it not very maintainable.
So what is the best way to implement this? I also want to add an extra class to the label if anyone can suggest how to do it?
For completeness, but not for your case: even after layout creation, Layout.wrap('recipients', Div) will work if one only needs to wrap a control into an additional Div.
About adding HTML inside the layout. Last hour I needed a very custom HTML, so did this:
(formatting)
i = self.helper.layout.fields.index('guest_email')
self.helper.layout.insert(
i+1,
HTML('{}'.format(
reverse_lazy('invite_guests'),
_('Invite to a party'))
))
I came here googling for a HTMLWrapper class example for Crispy Forms, so that I could do a prettier thing instead:
self.helper['guest_email'].wrap(HTMLWrapper(
'guest_email',
before='',
after='{}'.format(href, title))
If I end up creating one, I'll get back and post it.
For me it worked that way:
from crispy_forms.layout import Field, HTML
self.helper["some_field_name"].wrap(Field, HTML("<p>Example</p>"))
The benefit of using HTML is that it also gives you the possibility to use context variables.