Using stylesheets with django-widget-tweaks? - python

I'm struggling to understand how to use Django-Widget-Tweaks with a stylesheet. For example, here's my basic form with bunch of CSS classes pulled from my stylesheet - obviously not yet wired up with Django.
<form name="form">
<div class="md-form-group float-label">
<input type="email" class="md-input">
<label>Email</label>
</div>
</form>
How should this be used with Django-Widget-Tweaks? I'm presuming it's something like this but I'm struggling to understand where the div classes go...
<div>
{% load widget_tweaks %}
{{ form.myform|add_class:"md-form-group float-label md-input" }}
</div>
Thanks!

This is how I do it by using render_field tag. Hope this helps.
{% load widget_tweaks %}
<form name="form">
{% for field in form %}
<div class="md-form-group float-label">
{% render_field field class="md-input" %}
<label>{{ field.label_tag }}</label>
</div>
{% endfor %}
</form>

Related

How to iterate through numbers in django

I am new to Django. I just want to build an online resume based on the details given by the user.
I have separate HTML files for taking the user input and for displaying the resume.
I took the user input for the certification field like this:
<div class="box"><input type="text" name="certificate1" placeholder="Certificate-name"> <input type="text" name="institute1" placeholder="Institute-name"></div><br>
<div class="box"><input type="text" name="certificate2" placeholder="Certicate-name"> <input type="text" name="institute2" placeholder="Institute-name"></div><br>
<div class="box"><input type="text" name="certificate3" placeholder="Certicate-name"> <input type="text" name="institute3" placeholder="Institute-name"></div><br>
<div class="box"><input type="text" name="certificate4" placeholder="Certicate-name"> <input type="text" name="institute4" placeholder="Institute-name"></div><br>
<div class="box"><input type="text" name="certificate5" placeholder="Certificate-name"> <input type="text" name="institute5" placeholder="Institute-name"></div><br>
<div class="box"><input type="text" name="certificate6" placeholder="Certicate-name"> <input type="text" name="institute6" placeholder="Institute-name"></div><br>
And the code which I have written in views.py file is this:
if(request.method=="POST"):
dictionary = {str(i):request.POST[i].capitalize() for i in request.POST}
return render(request,"form/resume.html",dictionary)
And the code which I have written for displaying certifications in the resume is this:
{% if certificate1 %}
<li>{{certificate1}}, {{institute1}}</li>
{% endif %}
{% if certificate2 %}
<li>{{certificate2}}, {{institute2}}</li>
{% endif %}
{% if certificate3 %}
<li>{{certificate3}}, {{institute3}}</li>
{% endif %}
{% if certificate4 %}
<li>{{certificate4}}, {{institute4}}</li>
{% endif %}
{% if certificate5 %}
<li>{{certificate5}}, {{institute5}}</li>
{% endif %}
{% if certificate6 %}
<li>{{certificate6}}, {{institute6}}</li>
{% endif %}
But I feel the code that I have written in displaying certifications in resume [2nd code] is not efficient. Is there any other way of writing the 2nd code? I want to know, how can we use for loop if possible. Or is there any other way? Thanks in advance for your valuable answers.
You can group all your data in one array and pass them in your render function so you could iterate it in your Jinja template
Send certificates as a list to template like this:
certificates = [
{ "certificate": certificate1, "institute": institute1},
{ "certificate": certificate2, "institute": institute2}
]
Then in template, display it like this:
{% for c in certificates %}
<li>{{c.certificate}}, {{c.institute}}</li>
{% endfor %}
Try to use arrays so you can easily iterate through it.
or if you just want to write in that way
use string concatenation for the variable name like:
{% for x in '123456' %}
{% with y=forloop.counter|stringformat:"s" %}
{% with names="certificate"|add:y %}
{% if names %}
<li> {{name}} </li>
{% endif %}
{% endwith %}
{% endwith %}
{% endfor %}
See this for more info:
How can I concatenate forloop.counter to a string in my django template

Django forloop and all selectable radio buttons

Here is a seemingly simple task, creating a form using a set of records so the user can choose which record to go for, all using a radio button.
<form action="" method="GET">{% csrf_token %}
{% for record in select_records %}
<div class="form-check indent-3">
<label class="form-check-label" for="radio{{forloop.counter}}">
<input type="radio" class="form-check-input" id="radio{{forloop.counter}}" name="{{record.get_model_name}}{{record.id}}" value="{{record.record_name}}">
{% if request.user.userprofile.head_shot_thumb %}
<img src="{{ request.user.userprofile.head_shot_thumb }}" alt="Proforma creator">
{% else %}
<div class="h2-li ">
<i class="fas fa-user"></i>
</div>
{% endif %}
{{ record.record_name }} - {{ record.date_created }}
</label>
</div>
{% endfor %}
The problem is that the form creates a list of radio buttons which are all selectable, just like how all the checkboxes are selectable.
I have searched and compared my code to simple radio forms such as the one at W3schools, but I cannot figure it out. Any help is appreciated.
I did small changes in your code. Check it below.
<form action="" method="GET">
{% csrf_token %}
{% for record in select_records %}
<div class="form-check indent-3">
<label class="form-check-label" for="radio{{forloop.counter}}">
<input type="radio" class="form-check-input" id="radio{{forloop.counter}}" name="record-option" value="{{record.record_name}}">
{% if request.user.userprofile.head_shot_thumb %}
<img src="{{ request.user.userprofile.head_shot_thumb }}" alt="Proforma creator">
{% else %}
<div class="h2-li ">
<i class="fas fa-user"></i>
</div>
{% endif %}
{{ record.record_name }} - {{ record.date_created }}
</label>
</div>
{% endfor %}
</form>
I hope this will help you. :)

Django: Extent with snippets or better solution

I have the following template:
{% extends "account/base.html" %}
{% load i18n %}
{% load account %}
{% load crispy_forms_tags %}
{% block head_title %}{% trans "Password Reset" %}{% endblock %}
{% block content %}
<div class="container">
<div class="row justify-content-center">
<div class="col-8">
<h1>Reset your password</h1>
{% if user.is_authenticated %}
{% include "account/snippets/already_logged_in.html" %}
{% endif %}
<p>{% trans "Forgotten your password? Enter your e-mail address below, and we'll send you an e-mail allowing you to reset it." %}</p>
<form method="POST" action="{% url 'account_reset_password' %}" class="password_reset">
{% csrf_token %}
{{ form|crispy }}
<button type="submit" class="btn btn-primary">Reset My Password</button>
</form>
<p><em>{% blocktrans %}Please contact us if you have any trouble resetting your password.{% endblocktrans %}</em></p>
</div>
</div>
</div>
{% endblock %}
account/base.html contains this here:
{% extends "base.html" %}
base.html then contains tags etc. I am currently struggling with finding the best solution while considering DRY. In my template I have written:
<div class="container">
<div class="row justify-content-center">
<div class="col-8">
[more text]
</div>
</div>
</div>
I have several of these templates and in each of them I am currently writing the same ... I am now wondering is the right solution to include these opening / closing div-tags in two files and then add
{% include "div-open.html" %}
[more text]
{% include "div-closing.html" %}
Or is there any better solution to this? It doesn't feel right, that's why I am asking you now how you would solve this.
I depends if HTML repetition should be considered as DRY violation. I you have custom form fields which you want to include, than having {% include 'simple_custom_field.html' with field=form.some_fied %} where
simple_custom_field.html
<input
type="{{ field.field.widget.input_type }}"
class="form-control {{ field.field.widget.attrs.class }} {{ class }}"
id="{{ field.id_for_label }}"
name="{{ field.html_name }}"
placeholder="{{ field.label }}"
{% if field.value is not None %} value="{{ field.value }}"{% endif %}>
or like that...
is good idea, or you can render whole form like that also if you have long blocks or separate blocks of HTML in multiple files, then go for it. But its bad idea for including simple and fundamental parts of HTML. It should be transparent for the programmer.
If you want to do it another way, there are ways how to add custom template tags and "modify" the language you write templates in.
Here is docs how to do it: Writing custom template tags | Django docs

Reference list items by index Django template

I have a list called forms which I am passing to a Django (1.5.1) template:
<div class="content">
{% if forms %}
<form method="POST" enctype="multipart/form-data" class="survey">
<div class="image">
{{ forms.0.as_p }}
</div>
<div class="questions">
{% for form in forms %}
{{ form.as_p }}
</div>
{% endfor %}
<input type="submit" value="Submit Survey"/>
</form>
{% endif %}
<div class="content">
I want to do two separate things:
Put the first element of the forms list inside a div tag with class="image".
Put the rest of the elements inside a div tag with class="questions"
There are SO questions about how to reference list items by index inside a django template, but forms.0.as_p doesn't render anything for me. Also, how to get a sublist of items from forms (something like forms[1:])?
EDIT
While the question has been correctly answered below, I'll add another way of doing it using slice.
<form method="POST" enctype="multipart/form-data" class="survey">
<div class="image">
{{ forms.0.as_p }}
</div>
<div class="questions">
{% with myforms=forms|slice:"1:"%}
{% for form in myforms %}
{{ form.as_p }}
{% endfor %}
{% endwith %}
</div>
Use the forloop.first variable to determine the first form in the list:
{% for form in forms %}
<div class="{{ forloop.first|yesno:'image,question' }}">
{{ form.as_p }}
</div>
{% endfor %}
P.S. You don't need it for this case but to get the sublist in the template you can use the slice template filter.

Getting from POST in included .html page in Django

I am trying to get the POST values of an .html page that has included pages via {% include %} in Django. However, it returns only the POST from the initial html page.
My inner html that is included has the snippet of code:
div id="edit_parameters">Edit Parameters</div>
<div data-id="{{job.slug}}" id="{{job.slug}}" class="collapse">
<form class = "form-inline" method="post">
{% csrf_token %}
{% for parameter in job.get_object.parameters %}
<p>
<input type="text" class="input-small" name="{{parameter}}" value="" id ="{{parameter}}-input" placeholder="{{parameter}}">
</p>
{% endfor %}
<button type="submit" class="btn btn-primary run-job">Submit</button>
</form>
</div>
{% else %}
<div>
No editable parameters for this job.
</div>
{% endif %}
And my outer HTML file has a snippet:
<ul id="available-jobs">
{% if jobs_same_io_type and jobs_diff_io_type %}<h3> Current Step </h3>
{% elif jobs_same_io_type %} <h3> Next Step </h3> {% endif %}
{% for job in jobs_same_io_type %}
{% include "includes/job_li.html" with add=1 %}
{% endfor %}
{% if jobs_diff_io_type %} <h3> Next Step </h3> {% endif %}
{% for job in jobs_diff_io_type %}
{% include "includes/job_li.html" with add=1 %}
{% endfor %}
{% if not jobs_same_io_type and not jobs_diff_io_type %}
<li class="full-height">There are no more available jobs.</li>
{% endif %}
</ul>
<fieldset class="submit">
{% csrf_token %}
<input type="hidden" name="job_to_run" value="" id="job-to-run" />
<input type="hidden" name="workflow_jobs" value="" id="ordered-jobs" />
<input type="hidden" name="job_to_edit" value="" id="job-to-edit" />
<input type="hidden" name="job_to_add" value="" id="job-to-add" />
<input type="hidden" name="job_to_remove" value="" id="job-to-remove" />
<input type="submit" name="done" value="I'm done, start the jobs" id="jobs-ready" />
</fieldset>
The everything that shows in post is in the inputs of the second snippet. But the parameters I want for the first snippet are not included when I use request.POST for all of the POST values.
Any help would be greatly appreciated in explaining why I am not getting the values from the included page and finding a possible solution. Thanks!
In HTML, only the fields in the form element that contain the submit button are included in the POST. the fields in your second file don't seem to be in any form at all, so they will never be posted.

Categories