I'm trying to build an html page in Django, where depending on the form passed the page will render different things. How can I know in the HTML the type of form passed?
I want to do something like this:
{% block content %}
<div class="content-section container" >
{% if form.type == 'ModelAForm' %}
<div class="content-section">
<form method="POST" enctype="multipart/form-data">
{% csrf_token %}
{{ form.driver_color }}
</form>
</div>
{% endif %}
{% if form.type == 'ModelBForm' %}
<div class="content-section">
<form method="POST" enctype="multipart/form-data">
{% csrf_token %}
{{ form.driver_name}}
</form>
</div>
{% endif %}
</div>
{% endblock content %}
On the {% if form.type == 'ModelAForm' %} how can I know the form type?
Related
I have been working on a website for the past while using flask, python and bootstrap. I added footer to my website and I would like a "contact me" form in the footer. Below is my current code for creating a contact form and displaying this form.
class ContactForm(FlaskForm):
email = StringField("", validators=[DataRequired(), Email()])
content = TextAreaField("", validators=[DataRequired(), length(min=2, max=500)])
submit = SubmitField("Submit")
<form method="POST" action="">
<div class="form-group">
{{ form.email.label(class="form-control-label") }}
{% if form.email.errors %}
{{ form.email(class="form-control form-control-lg is-invalid") }}
<div class="invalid-feedback">
{% for error in form.email.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{{ form.email(class="form-control form-control-lg") }}
{% endif %}
</div>
<div class="form-group">
{{ form.content.label(class="form-control-label") }}
{% if form.content.errors %}
{{ form.content(class="form-control form-control-lg is-invalid") }}
<div class="invalid-feedback">
{% for error in form.content.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{{ form.content(class="form-control form-control-lg") }}
{% endif %}
</div>
<div class="form-group">
{{ form.submit(class="btn btn-outline-info") }}
</div>
</form>
I created this footer in my "layout.html" file which is the base file that all other html documents extend from so that all pages will have this same footer.
The issue is that then I need to create and instance of this form object on every page of my application and handle the validate_on_submit on every page. (Sample code below)
#app.route("/random_page", methods=["GET", "POST"])
def random_page():
form = ContactForm()
if form.validate_on_submit():
# code to send the email goes here
return render_template("random_page")
I am looking for an easier way to do this so that I don't need to repeat code on every page and so that It can be considerably simpler. I am not very experienced with flask and would highly appreciate the help.
Use the #app.context_processor decorator, documentation to inject an instance of your contact form into the template context for all templates. For example:
#app.context_processor
def inject():
return dict(
contact_form=ContactForm(),
)
Then re-write the form's HTML to use the contact_form template variable, also adding in an appropriate action route.
<form method="POST" action="{{url_for('contact')}}">
<div class="form-group">
{{ contact_form.email.label(class="form-control-label") }}
{% if contact_form.email.errors %}
{{ contact_form.email(class="form-control form-control-lg is-invalid") }}
<div class="invalid-feedback">
{% for error in form.email.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{{ contact_form.email(class="form-control form-control-lg") }}
{% endif %}
</div>
<div class="form-group">
{{ contact_form.content.label(class="form-control-label") }}
{% if contact_form.content.errors %}
{{ contact_form.content(class="form-control form-control-lg is-invalid") }}
<div class="invalid-feedback">
{% for error in contact_form.content.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{{ contact_form.content(class="form-control form-control-lg") }}
{% endif %}
</div>
<div class="form-group">
{{ contact_form.submit(class="btn btn-outline-info") }}
</div>
</form>
Then add a route to solely handle this form's postback:
#app.route("/contact", methods=["POST"])
def contact():
form = ContactForm()
if form.validate_on_submit():
# code to send the email goes here
# blah blah
I always receive a NoReverseMatch error, and I don't know why.
This is the error message:
NoReverseMatch at /suche/any-thing/
Reverse for 'article_search' with arguments '(u'any thing',)' not found. 1 pattern(s) tried: ['suche/(?P[-\w]+)/$']
So as you can see, I'm entering a url with "-" instead of whitespace, but Django is looking for url pattern with the space instead of "-".
This is my url pattern:
url(r'suche/(?P<search>[-\w]+)/$', views.article_search_view, name='article_search'),
Surprisingly Django starts to compute my article_search_view, which looks like this:
def article_search_view(request, search=None):
"""Filters all articles depending on the search and renders them"""
articles = get_active_not_rented_articles()
search = re.sub(r"[-]", ' ', search)
articles = articles.filter(title__icontains=search)
articles = aply_sort(request, articles)
orderd_by = articles[0].get('filter')
articles = articles[1]
return render(request, 'article/list.html', {'object_list':articles, 'url_origin':'article_search', 'parameter':search,
'orderd_by':orderd_by})
As I checked with "print()" statements, the error is raised when the return render(...) statement is called.
If I do a return redirect(...) instead, no error will be raised.
For completeness, my article/list.html template:
{% extends "base.html" %}
{% load static %}
{% block content %}
<div id =articles>
<div class="info_filter">
<div class="header_info_filter">
{% if orderd_by == "not" %}
<h1>Neueste Artikel</h1>
{% endif %}
{% if orderd_by == "distance" %}
<h1>Artikel in Ihrer Nähe</h1>
{% endif %}
{% if orderd_by == "price_asc" %}
<h1>Günstigste Artikel zuerst</h1>
{% endif %}
{% if orderd_by == "price_des" %}
<h1>Teuerste Artikel zuerst</h1>
{% endif %}
</div>
<div class="selection">
{% if parameter1 %}
<form action="{% url url_origin parameter1 parameter2 %}" method="post" accept-charset="utf-8">
{% else %}
{% if parameter %}
<form action="{% url url_origin parameter %}" method="post" accept-charset="utf-8">
{% else %}
<form action="{% url url_origin %}" method="post" accept-charset="utf-8">
{% endif %}
{% endif %}
{% csrf_token %}
<div class="select_filter">
<select name="filter" id="filter" >
<option value="distance">Entfernung</option>
<option value="price_asc">Preis, aufsteigend</option>
<option value="price_des">Preis, absteigend</option>
</select>
<div class="search_filter_btn">
<button type="submit" name="button">Sortieren</button>
</div>
</div>
</form>
</div>
{% if parent_categorys %}
<div class="category-path">
Ergebnisse für:
{% for category in parent_categorys %}
> {{ category.name }}
{% endfor %}
{% if parameter2 %}
: {{ parameter2}}
{% endif %}
</div>
{% else %}
Ergebnisse für: {{ parameter}}
{% endif %}
</div>
<div id="main" class="article_list">
{% for article in object_list %}
<div class="item">
<div class="list_img">
<a href="{{ article.get_absolute_url }}">
<img src="{% if article.main_picture %}{{ article.main_picture.url }}{% else %}{% static "img/no_image.png" %}{% endif %}">
</a>
</div>
<div class= "articles_fee" >
{{ article.fee }} €
</div>
{{ article.title }}
</div>
{% endfor %}
</div>
</div>
{% endblock %}
Let me know if you need more information.
In your view, you change search and replace hyphens with spaces. This causes an error when you use the url tag in your template, because the URL pattern does not allow spaces.
{% url url_origin parameter %}
You could fix the problem by adding the original search slug to the template context:
def article_search_view(request, search=None):
"""Filters all articles depending on the search and renders them"""
search_slug = search
articles = get_active_not_rented_articles()
search = re.sub(r"[-]", ' ', search)
...
return render(request, 'article/list.html', {'object_list':articles, 'url_origin':'article_search', 'parameter':search, 'search_slug': search_slug, 'orderd_by':orderd_by})
Then change the url tag:
{% url url_origin search_slug %}
I have a form in django:
country=forms.MultipleChoiceField(choices=lista_tari, widget=forms.CheckboxSelectMultiple(),required=True)
What i want is to display this form on multiple columns in the webpage. There are 30 choices, i want them on 6 or 5 or whatever columns.
This is the search.html:
{% block content%}
<form method="POST" class="post-form">{% csrf_token %}
{{ form.as_p }}
<button type="submit" class="save btn btn-default">Save</button>
</form>
{% endblock %}
I am brand-new to css, html and even django so any help would be of great help.
Thank you!
{% for field in form %}
{% ifequal forloop.counter 6 %}</ul><ul>{% endifequal %}
<li>{{ field }}</li>
{% endfor %}
you can try something like this
<form method="POST" class="post-form">{% csrf_token %}
<div class="form-check form-check-inline">
{% for field in form %}
{% if forloop.counter|divisibleby:3 %}</div><div class="form-check form-check-inline">{% endif %}
{{ field.errors }}
{{ field.label_tag }} {{ field }}
{% endfor %}
</div>
<button type="submit" class="save btn btn-default">Save</button>
</form>
But probably you should use django-bootstrap3 which helps you to integrate django and bootstrap.
I have created a admin panel on the frontend and would like to show different layouts if they are on the index.html or if they are on pages after /admin e.g:
/admin/dashboard
/admin/posts
/admin/media
My if statement:
{% if request.path == "/admin" %}
It doesn't work for some reason and I can't figure out why. This is an example of the whole if:
<div class="row">
{% if request.path == "/admin" %}
<div class="col-md-full">
{% else %}
<div class="col-md-7 left">
{% block main %}{% endblock %}
</div>
{% endif %}
{% if request.path == "/admin" %}
{% trans "Empty" %}
{% else %}
<div class="col-md-3 right">
<div class="panel panel-default">
<div class="panel-body">
{% block right_panel %}
{% endblock %}
</div>
</div>
</div>
{% endif %}
</div>
what about?
{% if '/admin/' in request.path %}
I am trying to use Crispy forms with Django-userena to make it look better but when ever I put the Crispy form tags in it duplicates the form,
My code is as followed:
{% extends 'userena/base_userena.html' %}
{% load i18n %}
{% load url from future %}
{% load crispy_forms_tags %}
{% block title %}{% trans "Signin" %}{% endblock %}
{% block content %}
<form action="" method="post" class="formholder">
{% csrf_token %}
{{ form|crispy }}
<fieldset>
<legend>{% trans "Signin" %}</legend>
{{ form.non_field_errors }}
{% for field in form %}
{{ field.errors }}
{% comment %} Displaying checkboxes differently {% endcomment %}
{% if field.name == 'remember_me' %}
<p class="checkbox">
<label for="id_{{ field.name }}">{{ field }} {{ field.label }}</label>
</p>
{% else %}
<p>
{{ field.label_tag }}
{{ field }}
</p>
{% endif %}
{% endfor %}
</fieldset>
<input type="submit" value="{% trans "Signin" %}" />
<p class="forgot-password">{% trans "Forgot your password?" %}</p>
{% if next %}<input type="hidden" name="next" value="{{ next }}" />{% endif %}
</form>
{% endblock %}
Solution by OP.
The problem was that the, {{ form|crispy }} was actually creating the form in the form.py file all I had to do was remove all the other from tags and just keep the {{ form|crispy }}
Here is what it looks like:
{% extends 'userena/base_userena.html' %}
{% load i18n %}
{% load url from future %}
{% block title %}{% trans "Signin" %}{% endblock %}
{% block content %}
{% load crispy_forms_tags %}
<form action="" method="post" class="formholder">
{% csrf_token %}
<fieldset>
<legend>{% trans "Signin" %}</legend>
{{ form|crispy }}
</fieldset>
<input type="submit" value="{% trans "Signin" %}" />
<p class="forgot-password">{% trans "Forgot your password?" %}</p>
{% if next %}<input type="hidden" name="next" value="{{ next }}" />{% endif %}
</div>
</form>
{% endblock %}