Django label_tag required asterisk - python

I am currently working on some Django templates and would like to put an asterisk after the label of required fields.
First of all I have found this syntax which works just fine but it makes me type a lot of code that is not required without the required asterisk.
<div>
{{ field.errors }}
<label for="{{ field.auto_id }}">
{% if field.field.required %}<span class="required">{{ field.label }}</span>
{% else %}{{ field.label }}{% endif %}
</label>
{{ field }}
</div>
This is the code I currently have in my template:
<div>
{{ field.errors }}
{{ field.label_tag }}{{ field }}
</div>
This way it saves a lot of code to write, but I can't figure out how to get the asterisk after the label with a required field.
Could someone help me with this?
If you need some more info feel free to ask.

Have you tried setting the required_css_class = 'something' on the form (cf here) Then using css you could add a red asterisk on the label

Consider writing a template tag that takes in field and returns field.label suffixed with an asterisk if the field is required, and field.label if not. And you can use like so:
<div>
{{ field.errors }}
{{ field | append_ast_if_req }}
{{ field }}
</div>
Your template tag can be:
#register.filter
def append_ast_if_req (field):
if field.field.required:
return field.label + '*'
else:
return field.label

Related

How to style django-multiselectfield with CSS

I am using 'django-multiselectfield' in my model form so users can select multiple 'areas' in my form. What I want to know now is how can I style the multiselectfield using css.
I have tried simply adding a class to the form field in my template like I normally do with all the other types of model fields, but no luck:
{% render_field form.area class="area" %}
Any help would be much appreciated.
This is described in `django-multiselectfield' documentation. Specifically,
It is possible to customize the HTML of this widget in your form template. To do so, you will need to loop through form {field}.field.choices. Here is an example that displays the field label underneath/after the checkbox for a MultiSelectField called providers:
Here is a example of what i did.
{% for field in form %}
<div class="fieldWrapper">{{ field.errors }}
<input type="{{ field.field.widget.input_type }}" name="{{ field.html_name }}" id="{{field.id_for_label}}" class="col-12 input-login" placeholder="{{field.label}}" >
{% if field.help_text %}
<p class="help">{{ field.help_text|safe }}</p>
{% endif %}
</div>
{% endfor %}
Now you can customise the field as if it is a simple html input field.
This page has a wonderful detailed explanation. Kudos to Vitor
------edit-----
Almost forgot. This is the example for normal forms. You have to go through the official docs of django-multiselectfield to get field attribute names, and replace the respective attributes
I suggest you render the form manually and loop through it.
Say you have a Choice model with a foreignkey to a Question model, you could do it like this:
<form class="qform" action="" method="post">
{% csrf_token %}
<p class="title">{{ form.question }}</p>
{% for choice in form.choice_set.all %}
<input type="checkbox" name="{{ choice }}" id="{{ choice }}{{ forloop.counter }}"
value="{{ choice.id }}">
<label for="{{ choice }}{{ forloop.counter }}">{{ choice }}</label>
{% endfor %}
</form>
You can reference the input and label in your style.css like:
input[type="checkbox"]{
some: stuffs...;
}
label {
some: stuffs...;
}
I hope this helps.

Format jinja2 template if type is none?

I am attempting to display some information back to a user. A phone number from a string in a database. Each client has 3 phone numbers, cell, home, other. At least one will be filled out but the others can be null.
When I formatting the numbers in jinja I am getting an error for None type. Is there anyway to skip the formatting if the value is None? here is the code..
{% for entry in results %}
<div class="panel-heading">{{ entry.firstName }} {{ entry.lastName }}</div>
<div class="panel-body">
<li>Email: {{ entry.email }}</li>
<li>Cell Phone: {{ "%s-%s-%s" | format(entry.cellNum[0:3], entry.cellNum[3:6], entry.cellNum[6:10]) }}</li>
<li>Home Phone: {{ entry.homeNum }}</li>
<li>Other Phone: {{ entry.otherNum }}</li>
<form action="#" method="post" class="sky-form">
<input type="hidden" value="{{ entry.id }}" name="firstname">
<button type="submit" class="button">Select Client</button>
</form>
</div>
{% endfor %}
Any thoughts?
Jinja can display None types as "None". So that shouldn't be the issue.
The issue is most likely this part:
{{ "%s-%s-%s" | format(entry.cellNum[0:3], entry.cellNum[3:6], entry.cellNum[6:10]) }}
if cellNum is None or undefined etc. this will not work as it tries to reference the value. so call a if on cellNum first.
{% if entry.cellNum %}{{ "%s-%s-%s" | format(entry.cellNum[0:3], entry.cellNum[3:6], entry.cellNum[6:10]) }}{% endif %}
Also, I'm assuming that all your entries in results is a valid value/object to do this with, you may want to check that too.
how about
{% if entry.homeNum %}{{ entry.homeNum }}{% endif %}
test data before using.

Flask-security and Bootstrap

How can I style my Flask-security login site with Bootstrap? The html form looks like this:
<form action="{{ url_for_security('login') }}" method="POST" name="login_form">
{{ login_user_form.hidden_tag() }}
{{ render_field_with_errors(login_user_form.email) }}
{{ render_field_with_errors(login_user_form.password) }}
{{ render_field_with_errors(login_user_form.remember) }}
{{ render_field(login_user_form.next) }}
{{ render_field(login_user_form.submit) }}
</form>
Bootstrap is implemented, but I dont know how to edit the fields and the submit button..
The render_field_* functions accepts a class_ parameter, which will add HTML classes to the field. Add in bootstrap styling classes as you want.
render_field_with_errors(login_user_form.email, class_="form-control") }}
{{ render_field(login_user_form.submit, class_="btn btn-default") }}
And so on.
Flask-Security uses Flask-WTForms to render and validate forms. In Flask-Security 1.7.5, the default render_field_with_errors and render_field macros defined in "security/_macros.html" are
{% macro render_field_with_errors(field) %}
<p>
{{ field.label }} {{ field(**kwargs)|safe }}
{% if field.errors %}
<ul>
{% for error in field.errors %}
<li>{{ error }}</li>
{% endfor %}
</ul>
{% endif %}
</p>
{% endmacro %}
{% macro render_field(field) %}
<p>{{ field(**kwargs)|safe }}</p>
{% endmacro %}
According to the Flask-WTForms 0.10 docs, both of the above macro functions accept ...
... keyword arguments that are forwarded to WTForm’s field function that renders the field for us. The keyword arguments will be inserted as HTML attributes.
Specifically, the lines {{ field(**kwargs)|safe }} pass the HTML escaped keyword arguments to the field function. Therefore, you can add classes,
{{ render_field_with_errors(login_user_form.email, class="form-control") }}
and can also overwrite default HTML attributes,
{{ render_field_with_errors(login_user_form.email,
class="form-control", type="email", placeholder="Enter email") }}
{{ render_field(login_user_form.submit, class="btn btn-default", value="Submit" ) }}
Additionally, you can define your own macros by modifying the macros above. For example, if you wanted to use Bootstrap alerts to render form validation errors, you could define the macro function render_field_with_bootstrap_errors
{% macro render_field_with_bootstrap_errors(field) %}
<p>
{{ field.label }} {{ field(**kwargs)|safe }}
{% if field.errors %}
{% for error in field.errors %}
<div class="alert alert-danger" role="alert">{{ error }}</div>
{% endfor %}
{% endif %}
</p>
{% endmacro %}
Adding your own macro is pretty simple. For example, you can put custom macros in a "custom_macros.html" file within the templates directory and then load the functions into templates with
{% from "custom_macros.html" import render_field_with_bootstrap_errors %}
This way, it is easy to modify the macros to use different Bootstrap features.

breaking form fields up separately django

I have a form that makes 14 fields, an opening and closing field for each day. I am having problems displaying each on its own, so I can include the days in between. My form is making fields such as 'open_time_1', 'close_time_1' up to 7. I currently have
{{ schedule_form.fields.close_time_1 }}
in my template, which was promising, but is causing
How can I get the nitty gritty of django form fields in general to display manually like that? Thank you
I would try {{ schedule_form.close_time_1 }}.
This renders the field without any label markup. This is some code I use to render a field with bootstrap:
<div class="form-group">
<span class="field-label">{{ field.label_tag }}</span>
{% if field.field.required %}<span class="required">*</span>{% endif %}
<span class="field-item">{{ field }}</span>
<div class="field-help">{{ field.help_text }}</div>
{% if field.errors %}<div class="alert alert-warning" role="alert">{{ field.errors }}</div>{% endif %}
</div>
Where field is eg. schedule_form.close_time_1.
More on the topic in Django docs: Working with forms.

Is there a way to hide the csrf label while looping through form using Flask and Flask-WTForms?

I have very simple contact form and I would like to hide the label somehow so that it doesn't show Csrf Token. I am using Flask and Flask-WTForms and am rendering the form like this:
{% for field in form %}
{{ field.label }}
{{ field }}
{% endfor %}
So basically this shows my inputs correctly and the csrf oen is hidden but the label isn't hidden? Should I get over it and implicitly say form.field_name instead of looping through the form or is there a way to handle this "corner case".
I was thinking about doing a logical check in either the for loop declaration or the label declaration but so far I haven't found anything in the documentation that has worked.
Thanks
EDIT: I have "fixed" the problem by doing this but it feels kinda dirty and hacky which I don't like I am still open to a better solution:
{% if not loop.first %}
{{ field.label }}
{% endif %}
If you want a more general solution that works for all hidden fields instead of just the CSRF token:
{{ form.hidden_tag() }}
{% for field in form if field.widget.input_type != 'hidden' %}
{{ field.label }}
{{ field }}
{% endfor %}
form.hidden_tag() is supplied by Flask-WTF.
Just to add to JD's excellent answer...
For those stumbling across this question: You can avoid losing the (csrf) hidden field (and thus protection) by adding the condition "if field.widget.input_type!='hidden' " specifically to the label instead of to the form iterator.
i.e.:
not
{{ form.hidden_tag() }}
{% for field in form if field.widget.input_type != 'hidden' %}
{{ field.label }}
{{ field }}
{% endfor %}
but
{{ form.hidden_tag() }}
{% for field in form %}
{% if field.widget.input_type != 'hidden' %} {{ field.label }} {% endif %}
{{ field }}
{% endfor %}
I think this should work too:
{% for field in form if field.id != 'csrf_token' %}
{{ field.label }}
{{ field }}
{% endfor %}
I have found the way to do it like this:
{% if field.id != 'csrf_token' %}
I believe this to be less hacky. I found this from modifying the example here in the docs.
I made a macro recently to submit forms through ajax in order to not reload the webpage and send it to the api directly.
{% macro render_fields3(form, form_name, method) %}
<form class="ajax" name={{ form_name }} method={{ method }}>
{{ form.hidden_tag() }}
{% for field in form if field.widget.input_type != 'hidden' %}
<dt>{{ field.label }}
<dd>{{field(id=field.name + method)|safe}}
{% if field.errors %}
<ul class=errors>
{% for error in field.errors %}
<li>{{ error }}</li>
{% endfor %}
</ul>
{% endif %}
</dd>
{% endfor %}
</form>
{% endmacro %}

Categories

Resources