Django formtools SessionWizardView repopulating form on validation error - django

I've a django-formtools SessionWizardView wizard which works fine when all data is input. However, I have form validation going on within each step of the form and if a step is represented I cannot get the entered data to redisplay in some instances.
Here is a simple example. Required field description isn't entered byt field plan was entered. The validation error is reported and the form redisplayed.
I'm creating the plan checkboxes in the template as below.
{% for plan in PLANS %}
<div class="col-6">
<span class="form-radio form-radio-xl">
<input type="radio" id="id_job-plan_{{plan.id}}" name="job-plan" value="{{ plan.pk }}" required {% if wizard.form.plan.value == plan.pk %}checked{% endif %}>
<label for="id_job-plan_{{plan.id}}">{{ plan }} - {{plan.pk}} </label>
</span>
</div>
{% endfor %}
I expect {% if wizard.form.plan.value == plan.pk %}checked{% endif %} to be True in one instance and therefore checked. It isn't and I do not understand why not.
If I do {{ wizard.form.plan.value }} the displayed result looks the same as {{ plan.pk }}

Found the answer. It looks the same but {{ wizard.form.plan.value }} is a string. By using {{ wizard.form.plan.value|add:"0" }} I coerce it into an integer and now it works

Related

Override django form field

I've been research a lot about this, but don't get any answer accurate. Here's the deal: I want to override where forms.Field is used from my own, that is, where all classes that inherit from forms.Field, inherit from my own. Why? I like to add some properties that i'll use in every single field.
Anyone?
This is the code which i used, please keep in mind that this field is purely for text-fields, for passwords you have to manually override form value fields.
{% for field in form %}
<div class="custom_class_here ">
{% if field.errors%}
<div class="custom_class_here">
{{ field.errors }}
</div>
{% endif %}
{% if field.help_text %}
<p class="custom_class_here">{{ field.help_text|safe }}</p>
{% endif %}
<input type="{{ field.field.widget.input_type }}" name="{{ field.html_name }}" id="{{field.id_for_label}}" class="custom_class_here" placeholder="{{field.label}}" value= "{{field.value|default_if_none:''}}">
</div>
{% endfor %}
Also for checkbox, select, passwords dropdowns etc you have to write separate if conditions and and alter fields accordingly.
I referred Vitor's site

Django forms - looping through form choice fields, how to assign the ID?

I am looping through some form choice fields in my template, but when I post, the form is not valid as it is missing required field "subnets" however I have manually created the subnet checkboxes. The reason I believe it is failing is because the manually created objects do not have an id, is this right? and how do I assign the id?
template:
{% for value, text in form.subnets.field.choices %}
<div class="checkbox">
<label>
<input type="checkbox" id="subnets" value="{{ value }}" />{{ text }}
</label>
</div>
{% if forloop.counter|divisibleby:4 %}
</div>
<div class="col-xs-3">
{% endif %}
{% endfor %}
error:
subnets
This field is required.
Your checkboxes should have name attribute:
<input type="checkbox" id="subnets" name="subnets" value="{{ value }}" />{{ text }}

django admin get verbose name in template

I'm overriding the django admin/templates/admin/includes/fieldset.html
I want my checkbox labels to be wrapped around the checkbox, but I can't figure out a way to access the verbose name of the model. Normally I would just add a method to the model but since I'm doing this in the admin and want to do it for every model, everywhere without effort I was wondering if here was an easier way.
This is what I have so far:
{% if field.is_checkbox %}
<div class="checkbox">
<label for="{{ field.auto_id }}" class="vCheckboxLabel">
{{ field.field }}
{{ field.give_me_the_verbose_name_for_the_model_plsthx }}
</label>
{% if field.field.help_text %}
<p class="help-block">{{ field.field.help_text|safe }}</p>
{% endif %}
</div>
{% else %}
...
You can access verbose name by:
field._meta.verbose_name
But it works only in view, you haven't _meta in template.

FOSUserBundle: How to best integrate login and register form in one template?

I am using the FOSUserBundle in my Symfony application which is really great. They have the login and register forms in a separate template. I want both in one template to display them next to each other.
Therefore I created app/Resources/FOSUserBundle/Security/login.html.twig and app/Resources/FOSUserBundle/Registration/register.html.twig to override both templates. In login.html.twig I call the register controller to render its template.
app/Resources/FOSUserBundle/Security/login.html.twig:
{% extends "FOSUserBundle::layout.html.twig" %}
{% trans_default_domain 'FOSUserBundle' %}
{% block fos_user_content %}
{% if error %}
<div>{{ error|trans }}</div>
{% endif %}
<form action="{{ path("fos_user_security_check") }}" method="post">
<input type="hidden" name="_csrf_token" value="{{ csrf_token }}" />
<input type="text" id="username" name="_username" value="{{ last_username }}" placeholder="{{ 'security.login.username'|trans }}" required="required" />
<input type="password" id="password" name="_password" placeholder="{{ 'security.login.password'|trans }}" required="required" />
<input type="checkbox" id="remember_me" name="_remember_me" value="on" />
<label for="remember_me">{{ 'security.login.remember_me'|trans }}</label>
<input type="submit" id="_submit" name="_submit" value="{{ 'security.login.submit'|trans }}" />
</form>
{{ render(controller('FOSUserBundle:Registration:register')) }}
{% endblock fos_user_content %}
app/Resources/FOSUserBundle/Registration/register.html.twig:
{% include "FOSUserBundle:Registration:register_content.html.twig" %}
But then I get the following error:
FatalErrorException: Error: Maximum function nesting level of '100' reached, aborting! in /private/var/www/symfony/My_UserBundle/vendor/twig/twig/lib/Twig/Node/Expression/Array.php line 31
I don't know why I get this error message. If I look into the Security:login and Registration:register controller, the templates get rendered in different ways:
$this->renderLogin(...
and
$this->container->get('templating')->renderResponse('FOSUserBundle:Registration:register.html....
So basically I have two questions:
What does the error message mean and how can I solve it?
Maybe this approach is not ideal, is there a better solution for this?
You could use (as #Sidali Hallak said)
{% render url('fos_user_registration_register') %}
{% render url('fos_user_security_login') %}
But use your own versions of the FOSUserBundle:Registration:register.html.twig and FOSUserBundle:Security:login.html.twig templates that don't extend FOSUserBundle::layout.html.twig
To be compliant with newer Symfony versions, you should avoid using {% render %} tag and use {{ render(controller('MyBundle:ControllerClass:action')) }} instead:
{{ render(controller('FOSUserBundle:Security:login')) }}
{{ render(controller('FOSUserBundle:Registration:register')) }}
use :
{% render url('fos_user_security_login') %}
{% render url('fos_user_Registration_register') %}
The max nesting level comes from xdebug and can be resolved setting ...
xdebug.max_nesting_level = 200
... in your php.ini.

django form: how to check out checkbox state in template

I have a form with checkboxes that works fine, but when the user submits the form with errors and my checkbox is checked I need to change div class which holds the checkbox. So I was experimenting with {{ form.mycheckbox.data }} in the template and it says False on page load. Now when user is click on a checkbox and the form has errors, it says on. So I tried:
{{ if form.mycheckbox.data == True }} doesn't work
{{ if form.mycheckbox.data != False }} doesn't work
{{ if form.mycheckbox.data == 'on' }} doesn't work
{{ if form.mycheckbox.data == on }} doesn't work
Use {% if form.mycheckbox.value %}. This will evaluate to true if the box is checked. For the opposite behavior, use {% if not form.mycheckbox.value %}.
Note the syntax is {% if ... %}, not {{ if ...}}. Percent-brackets are for commands, double-brackets are for outputting variables.
In models.py:
class Article:
published = BooleanField()
(...)
In the template:
<input type="checkbox" name="published" {% if article.published %}checked{% endif %} />
Work for me:
{% for foo in form.tags %}
<label class="publication-tag">
<input class="publication-tag__checkbox"
{% if foo.choice_value in foo.value %}checked="checked"{% endif %}
type="checkbox"
name="{{ foo.name }}"
value="{{ foo.choice_value }}">
{% endfor %}
That:
{% if foo.choice_value in foo.value %}checked="checked"{% endif %}
While, first you should use BooleanField in your model, not the CharField.
Then, there are two accesses:
just put {{form.yourField}} in your template (preferred)
or, use {% if form.yourFiled.value %} checked {%endif%}