How can I get the validation errors from flask_wtforms - flask

I would like to get validation errors from a textarea form from flask_wtforms. I know that you can get them by including this in the html :
{% for error in form.post.errors %}
{{ error }}
{% endfor %}
But that doesn't quite work for me because Im using a bootstrap modal and the Length validation requires you to submit the form, refreshing the page, unlike the DataRequired() validator which prevents you from submitting. And its hard to tell that the form failed.
Basically I would like to get the errors from the python end and flash them.
I've tried to access the errors with form.post.errors but it doesn't work, it always returns an empty set.
This is the code for my index
def index():
form = PostForm()
// I would like to get the errors via form.post.errors here and I don't understand why I can't
if form.validate_on_submit():
post = Post(body=form.post.data, author=current_user)
db.session.add(post)
db.session.commit()
flash('Your post is now live!', 'primary')
return redirect(url_for('index'))
page = request.args.get('page', 1, type=int)
posts = current_user.followed_posts().paginate(page, app.config['POSTS_PER_PAGE'], False)
next_url = url_for('index', page=posts.next_num) if posts.has_next else None
prev_url = url_for('index', page=posts.prev_num) if posts.has_prev else None
return render_template('index.html', title='Home', posts=posts.items, form=form, next_url=next_url, prev_url=prev_url)
{% extends "base.html" %}
{% block content %}
{% if form %}
<div class="modal fade" id="submitPost" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<form action="" method="post">
{{ form.hidden_tag() }}
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="submitPostLabel">Submit Post</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<div class="form-group">
<label for="PostText">{{ form.post.label }}</label>
{{ form.post(cols=32, rows=4, class="form-control") }}<br>
</div>
</div>
<div class="modal-footer">
<!-- <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button> -->
{{ form.submit(class="btn btn-primary") }}
</div>
</div>
</form>
</div>
</div>
{% endif %}
the above html file is basically
<form action="" method="post">
{{ form.hidden_tag() }}
{{ form.post.label }}
{{ form.post(cols=32, rows=4, class="form-control") }}
{{ form.submit(class="btn btn-primary") }}
</form>
with some bootstrap

You can print the errors by adding the following: print form.errors.items().
form.errors

Related

How can I remove a particular item using a popup?

I have many items and I want to delete one of them but when I delete one item it turns out that it deletes the last item which exists based on ordering so, if I have 10 records of id which start from 1 to 10 record so, it will remove the item number 10 til if I remove item number 5 will remove the number 10. this case occurs because of popup but if I remove popup and delete the items directly it will remove with no mistake so, How can I remove a particular item using popup?
profile.html
{% if request.user == profile.user %}
<div class="col-lg-7 offset-lg-1 col-12">
{% if profile.user.user_history.all.count != 0 %}
<form method="post">
{% csrf_token %}
<div class="clear_all fl-left">
<input class="global_checkbox" type="checkbox" name="remove_all_history" id="remove_all_history">
<label for="remove_all_history" class="ml">Remove All</label>
</div>
<div class="fl-right">
<input type="submit" value="Remove" class="clear_button btn btn-danger invisible"/>
</div>
</form>
{% else %}
<p class="text-center">you have no history yet!</p>
{% endif %}
<div class="clearfix"></div>
<div class="mt-6"></div>
{% for history in history_pages %}
{% if history.deleted_history == False %}
<div class="history">
<div class="row">
<div class="col-4">
<form method="post">
{% csrf_token %}
<input class="global_checkbox" type="checkbox" name="remove_one_history" id="remove_all_history">
<span class="ml-2">{{ history.history_time|time }}</span>
<div class="ml ml-4">{{ history.history_time|date:'d M Y' }}</div>
</form>
</div>
<div class="history-content col-7">
<p><strong>text:</strong> {{ history.history }}</p>
<p><strong>action:</strong> {{ history.action_option }}</p>
<p><strong>position:</strong>
{% if history.verb_option == "" %}
POS
{% else %}
{{ history.verb_option }}
{% endif %}
</p>
</div>
<form method="post" action="{% url 'accounts:remove_history' history.id %}">
{% csrf_token %}
<div class="history-list col-1">
<span class="fa fa-ellipsis-v" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"></span>
<div class="dropdown-menu">
<a type="button" class="dropdown-item" data-toggle="modal" data-target="#exampleModal">Remove this item</a>
</div>
</div>
{% include 'accounts/popup.html' %}
</form>
</div>
</div>
{% endif %}
{% endfor %}
</div>
{% endif %}
popup.html
<div class="modal fade" id="exampleModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Warning!!</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
Do you want to remove this history item?
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
<button type="submit" class="btn btn-outline-danger">Remove</button>
</div>
</div>
</div>
</div>
views.py
#login_required
def userProfile(request, slug=None):
profile = None
try:
profile = Profile.objects.get(user__slug=slug)
paginator = Paginator(profile.user.user_history.all(), 100)
page_number = request.GET.get('page_number')
history_pages = paginator.get_page(page_number)
except:
return redirect('accounts:index_404')
return render(request, 'accounts/profile.html', {'profile': profile, 'history_pages': history_pages})
def remove_history(request, id=None):
if id and id is not None:
# History.objects.get(id=id)
print(id)
return redirect("accounts:profile", request.user.username)
Note: I tested the delete using print(id)
In your current code you have included popup.html mutliple times so when you click on a tag its not confirm which modal will get open has all are triggering exampleModal i.e :data-target="#exampleModal" .
So , to overcome this one way would be including only one modal and adding form tags around submit button . Then , whenever user click on a tag you can get action value from form where a tag has been clicked and then add this action value inside modal form tag .
Demo Code :
//on click of `a` tag
$(".dropdown-item").on("click", function() {
//get closest form from `a` tag then get action from it
var action_ = $(this).closest("form").attr("action");
$("#exampleModal form").attr("action", action_) //add that action inside modal form tag
console.log(action_)
})
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
<div class="history">
<div class="">
<div class="">
<form method="post">
{% csrf_token %}
<input class="global_checkbox" type="checkbox" name="remove_one_history" id="remove_all_history">
<span class="">12:30</span>
<div class="">12-04-21</div>
</form>
</div>
<div class="history-content">
<p><strong>text:</strong> Somethigs</p>
<p><strong>action:</strong>Ok</p>
<p><strong>position:</strong> POS
</p>
</div>
<form method="post" action="{% url 'accounts:remove_history' 1 %}">
<div class="history-list">
<span class="fa fa-ellipsis-v" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"></span>
<div class="dropdown-menu">
<a type="button" class="dropdown-item" data-toggle="modal" data-target="#exampleModal">Remove this item</a>
</div>
</div>
<!--remove this line {% include 'accounts/popup.html' %}-->
</form>
</div>
</div>
<div class="history">
<div class="">
<div class="">
<form method="post">
{% csrf_token %}
<input class="global_checkbox" type="checkbox" name="remove_one_history" id="remove_all_history">
<span class="">12:32</span>
<div class="">22-04-21</div>
</form>
</div>
<div class="history-content">
<p><strong>text:</strong> Somethigs2</p>
<p><strong>action:</strong>Ok2</p>
<p><strong>position:</strong> POS
</p>
</div>
<form method="post" action="{% url 'accounts:remove_history' 2 %}">
<div class="history-list">
<span class="fa fa-ellipsis-v" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"></span>
<div class="dropdown-menu">
<a type="button" class="dropdown-item" data-toggle="modal" data-target="#exampleModal">Remove this item</a>
</div>
</div>
<!--remove this line {% include 'accounts/popup.html' %}-->
</form>
</div>
</div>
<!--just use only one modal no need to include it every time on your page-->
<div class="modal fade" id="exampleModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Warning!!</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<!--added form tag-->
<form method="post" action="">
<!--added csrf token-->
{% csrf_token %}
<div class="modal-body">
Do you want to remove this history item?
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
<button type="submit" class="btn btn-outline-danger">Remove</button>
</div>
</form>
</div>
</div>
</div>

Manually rendered form fields do not save data

I really wanted to figure this out myself and I spent over 4 hours on the subject but I give up now.
I have a form that is supposed to save data, and if I lay out the form with the {{ form }} tag everything works great. If I put in to form with individual tags like {{ form.client_email }}, the form data is not saved to the database.
I need to render these fields manually for front end purposes but I just couldn't figure out how to do it.
I appreciate your help a lot.
Here is my code.
views.py
def client_list_view(request):
if request.method == 'POST':
form = ClientModelForm(request.POST)
if form.is_valid():
client_title = form.cleaned_data["client_title"]
client_email = form.cleaned_data["client_email"]
client_turkishid_no = form.cleaned_data["client_turkishid_no"]
client_tax_no = form.cleaned_data["client_tax_no"]
client_tax_office = form.cleaned_data["client_tax_office"]
client_contactperson = form.cleaned_data["client_contactperson"]
client_phone_number = form.cleaned_data["client_phone_number"]
Client.objects.create(
client_title=client_title,
client_email=client_email,
client_turkishid_no=client_turkishid_no,
client_tax_no=client_tax_no,
client_tax_office=client_tax_office,
client_contactperson=client_contactperson,
client_phone_number=client_phone_number
).save()
return redirect("books:client-list")
else:
form = ClientModelForm()
client_list = Client.objects.all().order_by("client_title")
context = {'client_list' : client_list, "form": ClientModelForm}
return render(request, 'clients/client_list.html', context=context)
Working template
<div id="clientModal" class="modal bottom-sheet">
<div class="modal-content">
<form method="POST">
{% csrf_token %}
{{form}}
<button class="btn">Ekle</button>
</form>
</div>
</div>
Not Working Template
<div id="clientModal" class="modal bottom-sheet">
<div class="modal-content">
<div class="row">
<div class="col s12">
<ul class="tabs">
<li class="tab col m6"><a class="active" href="#gercek">Gerçek Kişi</a></li>
<li class="tab col m6"><a class="active" href="#tuzel">Tüzel Kişi</a></li>
</ul>
</div>
<div id="gercek" class="col s12">
<div class="col s12 m12 l12">
<div id="inline-form" class="scrollspy">
<div class="card-content">
<form method="POST">
{% csrf_token %}
<div class="row">
<div class="input-field col m4 s12">
<i class="material-icons prefix">email_outline</i>
{{form.client_email}}
<label for="{{ form.client_email.id_for_label }}">Müvekkilin E-Posta Adresi</label>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
<div id="tuzel" class="col s12">
<div class="col s12 m12 l12">
<div id="inline-form" class="scrollspy">
<div class="card-content">
<form method="POST">
{% csrf_token %}
<div class="row">
<div class="input-field col m4 s12">
<i class="material-icons prefix">account_circle</i>
{{form.client_title}}
<label for="{{ form.client_title.id_for_label }}">Müvekkilin Unvanı</label>
</div>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
In your "not working" template you wrap each of individually rendered field with a form tag. That's not the correct way to do what you need. Just keep one form tag like you do in the working template and render all fields inside:
<div id="clientModal" class="modal bottom-sheet">
<div class="modal-content">
<form method="POST">
{% csrf_token %}
<!-- put your fields here with any additional markup you need -->
{{ form.client_email }}
<label for="{{ form.client_email.id_for_label }}">Müvekkilin E-Posta Adresi</label>
{{ form.client_title }}
<label for="{{ form.client_title.id_for_label }}">Müvekkilin Unvanı</label>
<!-- by the way you can use form.<field>.label_tag -->
{{ form.client_phone_number }}
{{ form.client_phone_number.label_tag }}
<!-- and maybe you'd also like to render errors -->
{{ form.client_phone_number.errors }}
<button class="btn">Ekle</button>
</form>
</div>
</div>
Also, the ClientModelForm seems to be an instance of ModelForm, so you do not need to deal with form.cleaned_data manually. For new objects you can just call form.save(commit=True):
if form.is_valid():
form.save(commit=True)

Form Validation Not Displaying on Form

I have a custom form validation that runs on my popup window form. If the form validation occurs i get a bad request error which is what i have programmed in my views.py . How do i render it so the user stays on the form and the validation message displays. Thanks for the help. Here is my code.
#login_required
def K8_Points_Classroom(request):
#context_from_k8_points = request.session['k8_points_context']
if request.method == 'POST':
form = K8Points_ClassroomForm(request.POST)
if form.is_valid():
form.save(commit=False)
form.save()
class_name = form.cleaned_data.get('class_name')
getstudents = Student.objects.filter(class_name = class_name)
students = getstudents.all()
form = K8Points_ClassroomForm()
context = {'form': form ,'students' : students, 'class_name': class_name,}
return render(request,'points/k8_points_classroom.html', context)
else:
return HttpResponseBadRequest("Bad Request")
else:
return render(request, 'points/k8_points_classroom.html', {'form': form} )
Updated form.html
{% extends 'base.html' %}
{% load crispy_forms_tags %}
{% crispy K8Points_ClassroomForm %}
{% load static %}
{% block content %}
<br>
<h2>{% load static %}
<img src="{% static 'forms/star.png' %}" alt="chain" height="62" width="62"> {{class_name}}</h2>
<br>
<br>
<form action="/points/k8_points_classroom" method="POST">
{% csrf_token %}
<!-- Start Date -->
<div class="container">
<div class="container">
<div class='row'>
<div class="col-4">
<p> Recording Data as User : {{user.username}} </p>
</div>
</div>
<div class='row'>
<div class = "col-2">
{{form.date|as_crispy_field }}
</div>
<div class = "col-2">
{{form.week_of|as_crispy_field }}
</div>
<div class = "col-2">
{{form.day|as_crispy_field }}
</div>
</div>
</div>
</form>
<div class="jumbotron" align="middle">
<img src="{% static 'forms/levelup.png' %}" alt="levelup" height="120" width= "120">
<h1>My Students</h1>
<!-- Line Break -->
<hr style="border: 1px solid black;"/>
<!-- Line Break -->
<div class="row mb-3">
{% for i in students%}
<div class="col-md-4 themed-grid-col"><h2>{{i.student_name}}</h2>
<p align="left"> Today's Score: {{total}}</p>
<h4>
<button type="button" class="btn btn-primary btn-lg btn-block" data-toggle="modal"
data-target="#PointsBox{{ student.pk }}">Level Up
</button>
</h4>
<div id="PointsBox{{ student.pk }}" class="modal fade" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<img src="{% static 'forms/star.png' %}" align="left" alt="chain" height="42"
width="42">
<h4 class="modal-title">Points Confirmation </h4>
<button type="button" class="close" data-dismiss="modal"> ×</button>
</div>
<div class="modal-body">
<h6>
<div class="modal-body">Please add the selected points for the current
student.</div>
</h6>
<form action="/points/k8_points_classroom" method="POST">
{% csrf_token %}
<div class="form-row" align='left'>
<div class="col-7">
{{form.class_name|as_crispy_field }}
<input type="student_name" class="form-control" value ="{{i}}" >
{{form.time_frame|as_crispy_field }}
</div>
</div>
<div class="form-row">
<div class="col-3" align='left'>
{{form.behavior|as_crispy_field }}
{{form.academic|as_crispy_field }}
<button type="submit" class="btn btn-success" ><i
class="fas fa-star"></i> Level Up
</button>
</div>
</div>
</div>
<div class="modal-foot"></div>
</div>
</div>
</div>
</div>
</form>
{% endfor %}
{% endblock %}
You can't return a bad response if the form is invalid. Instead, render the page again with the invalid form and in the temolate you will be able to render the errors. Try starting rendering the form just using {{ form.as_p }} and you will see the errors. The form errors are in form.errors and each field has its own errors, you can access to them form.field.erorrs
if request.method == 'POST':
form = K8Points_ClassroomForm(request.POST)
if form.is_valid():
form.save(commit=False)
form.save()
class_name = form.cleaned_data.get('class_name')
getstudents = Student.objects.filter(class_name = class_name)
students = getstudents.all()
form = K8Points_ClassroomForm()
context = {'form': form ,'students' : students, 'class_name': class_name,}
return render(request,'points/k8_points_classroom.html', context)
return render(request, 'points/k8_points_classroom.html', {'form': form} )

Django, form can not be submitted

I created the form, but i can not submit it using post method. I worked with generic views
When i try to submit it,this link appeares '?csrfmiddlewaretoken=4u6glHHJVueXItlN...'
here's my code:
form template:
<form action="" method="post" class="form-inline">
{% csrf_token %}
<div class="modal-body clearfix">
{% include 'words/word_form.html' %}
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
<button type="submit" class="btn btn-primary">Save changes</button>
</div>
</form>
generic view:
class Create_Word(generic.CreateView):
model=Word
fields=['name','translation']
template_name = "words/list_all.html"
Here's word_form template:
{%load extra%}
{% for field in form %}
<div class="form-group ">
<div class="col-sm-10">
<span class="text-danger-small">{{ field.errors }}</span>
</div>
<label class="control-label col-sm-2 m-l-1 ">{{ field.label_tag }}</label>
<div class= "col-sm-9 m-b-1">
{{ field | addcss:"form-control" }}
</div>
{% endfor %}

Doesn't populate fields with existing data

When I access the update page it doesn't populate the fields with the existing entry data (which is there, and print statements I've placed in parts of the view show that it's accessible and exists), I'm not really sure why it's not populating.
This is my view:
#login_required
def sites_update_view(request, place_id=None):
if place_id:
place = get_object_or_404(SiteMeta, pk=place_id)
else:
return redirect('sites-index')
if request.POST:
form = SitesAddForm(request.POST, instance=place)
if form.is_valid():
form.save()
return redirect('sites-index')
else:
form = SitesAddForm(instance=place)
return render(request, 'sites-update.html', {
'form': form,
'site': place,
'place_id': place_id
})
My template:
{% extends "newbase.html" %}
{% load url from future %}
{% load floppyforms %}
{% load staticfiles %}
{% block title %} - Update Site {% endblock %}
{% block content %}
<div class="row">
<div class="col-sm-6 col-md-6">
<h3 class="heading">Update Surveillance Site</h3>
<form method="post" action={% url 'sites-update' place_id=site.pk %}>
{% csrf_token %}
<div class="formSep">
<div class="row">
<div class="col-sm6 col-md-6">
<label for="id_name">Site Name:<span class="f_req">*</span></label>
{{ form.name }}
<span class="help-block">What is the site name?</span>
</div>
<div class="col-sm-6 col-md-6">
<label for="id_lga">LGA:<span class="f_req">*</span></label>
{{ form.lga }}
<span class="help-block">What is the LGA?</span>
</div>
<div class="col-sm-6 col-md-6">
<label for="id_site_type">Site Type:<span class="f_req">*</span></label>
{{ form.site_type }}
<span class="help-block">What type of site is this?</span>
</div>
<div class="col-sm-6 col-md-6">
<label for="id_site_priority">Site Priority:<span class="f_req">*</span></label>
{{ form.site_priority }}
<span class="help-block">What is the priority of this site?</span>
</div>
<div class="col-sm-6 col-md-6">
<label for="id_site_category">Site Category:<span class="f_req">*</span></label>
{{ form.site_category }}
<span class="help-block">What category should the site be in?</span>
</div>
</div>
</div>
<div class="row">
<input class="btn btn-default" type="submit" value="Save" />
<a class="btn btn-default" href={% url "sites-index" %}>Cancel</a>
</div>
</form>
</div>
</div>
{{ form.errors }}
{% endblock %}
{% block sidebar %}
{% include "afp-sidebar.html" %}
{% endblock %}
if request.POST: should be if request.method == 'POST':