Messages are not being flashed when form errors in Flask - python

I've edited my question to be more clear. When I validate my form and it has errors, I flash my message but this does not end up rendered in my template:
#app.route('doit', methods=["GET", "POST"])
def doit():
form = MyForm()
if form.validate_on_submit():
flash('success')
else:
if form.errors:
print "You've got errors!"
flash('You have some errors')
print session['_flashes']
return render_template('test.html')
My template for displaying messages:
{% with messages = get_flashed_messages() %}
{{ messages }}
<br/>
{{ session }}
{% endwith %}
When I submit my form with errors, I flash flash("You have some errors"), and I DO see _flashes in the session holding my error message when I print my session to console:
# my console output
You've got errors!
[('message', 'You have some errors')]
However, when the template renders, {{ session }} does not have _flashes at all, and so get_flashed_messages() is always an empty list. No message is flashed as a result.
What am I doing wrong?

Okay guys, I was being rather dumb (again). Turns out the form was being POSTed through AJAX, but the result of the call was was expecting a JSON format and not the entire HTML template.
I've switched to returning a json response instead, and now it is fine.

The function get_flashed_messages() returns a list, which you should iterate over and print out the messages within, like this:
{% with messages = get_flashed_messages() %}
{% if messages %}
<ul>
{% for message in messages %}
<li>{{ message }}</li>
{% endfor %}
</ul>
{% else %}
No messages.
{% endif %}
{% endwith %}

Related

Django context isn't passing information to template

I try to pass information to an html template from a view function. Every time I try to call the variable from the html template it doesn't show anything.
Here is my configure_peplink.html:
{% extends "base_generic.html" %}
{% block content %}
<h1>Configure Peplink</h1>
<p>Configure a Peplink router from the web. This was designed by <em>Valorence LLC</em></p>
{% if peplink %}
<p>Serial Number: {{ peplink.serial_number }}</p>
<p>IP Address: {{ peplink.ip_address }}</p>
<p>Mac Address: {{ peplink.mac_address }}</p>
<p>Name: {{ peplink.name }}</p>
{% else %}
<p>No Data Found Off Device</p>
{% endif %}
{% endblock %}
Here is the view function configure_peplink:
def configure_peplink(request, peplink):
selected_peplink = PeplinkDevice.objects.get(serial_number=peplink)
print(selected_peplink.ip_address)
print(selected_peplink.serial_number)
print(selected_peplink.mac_address)
context = {
'peplink': selected_peplink
}
return render(request, 'configure_peplink.html', context=context)
Here is the url line to call the view:
re_path(r'^configurepeplink/(?P<peplink>.*)/$', views.configure_peplink, name='configurepeplink')
I've tested to make sure that the context has data in it (as seen with the print statements). Even though the context variable has data and is getting past the if statement in the html template it still doesn't display any data. I have tried clearing my cache on the browser and restarting all my services (django, celery, redis-server).
Here is a picture of the webpage:
The peplink variable (which is being used by the regex url and the view function) seems to be causing the problem. Change the name of the key or change the regex url variable for this to work. To get this to work by changing the key name in the view function do the following in the view function:
def configure_peplink(request, peplink):
selected_peplink = PeplinkDevice.objects.get(serial_number=peplink)
print(selected_peplink.ip_address)
print(selected_peplink.serial_number)
print(selected_peplink.mac_address)
context = {
'selected_peplink': selected_peplink
}
return render(request, 'configure_peplink.html', context=context)
Then change the html template to the following:
{% extends "base_generic.html" %}
{% block content %}
<h1>Configure Peplink</h1>
<p>Configure a Peplink router from the web. This was designed by <em>Valorence LLC</em></p>
{% if selected_peplink %}
<p>Serial Number: {{ selected_peplink.serial_number }}</p>
<p>IP Address: {{ selected_peplink.ip_address }}</p>
<p>Mac Address: {{ selected_peplink.mac_address }}</p>
<p>Name: {{ selected_peplink.name }}</p>
{% else %}
<p>No Data Found Off Device</p>
{% endif %}
{% endblock %}

Flask form validation error prompt message

I made a form to reset password, when I submit the form with an empty password, the error prompt words I set in views.py didn't show up at the <span> I left in a HTML, a default Fill out this field showed instead.
*fisrt one is old password, second one is new password
In forms.py:
class PwdForm(FlaskForm):
old_pwd = PasswordField(
label="OldPassword",
validators=[
DataRequired("Please input old password")
]
)
submit = SubmitField(
"Confirm"
)
In views.py:
#admin.route("/pwd_reset/", methods=["GET", "POST"])
#admin_login_req
def pwd_reset():
form = PwdForm()
if form.validate_on_submit():
data = form.data
admin = Admin.query.filter_by(name=session["admin"]).first()
from werkzeug.security import generate_password_hash
admin.pwd = generate_password_hash(data["new_pwd"])
db.session.add(admin)
db.session.commit()
flash("ok, now use your new password to login", "ok")
redirect(url_for("admin.logout"))
return render_template("admin/pwd_reset.html", form=form)
In html:
<label for="input_pwd">{{ form.old_pwd.label }}</label>
{{ form.old_pwd }}
{% for err in form.old_pwd.errors %}
<span style="color: #ff4f1f">{{ err }}</span>
{% endfor %}
How to make my own prompt message show up
I think you mean how do you get your flash message to display? Use the following code in your base template page or in each page. See: Message Flashing
{% with messages = get_flashed_messages() %}
{% if messages %}
<ul class="flashes">
{% for message in messages %}
<li>{{ message }}</li>
{% endfor %}
</ul>
{% endif %}
{% endwith %}

Rise error when try to delete protected foreign key in Django

I want the user to see an error message when he tries to delete a value that is being used as PROTECTED Foreign key for another table, and the table is not empty which means there are values under this Foreign key.. it returns back an error for me in debug mode but I want an error message for end user ...
view.py
def cat_delete(request, pk):
instance = get_object_or_404(Categories, pk=pk)
instance.delete()
return redirect('/')
urls.py
path('category/<int:pk>/delete/', views.cat_delete, name="cat_delete"),
HTML
<button type="button" class="btn btn-danger" >تأكيد المسح</button>
You can use the Django Messages Framwork
Your cat_delete view:
from django.contrib import messages
...
def cat_delete(request, pk):
instance = get_object_or_404(Categories, pk=pk)
try:
instance.delete()
except Exception as e:
messages.error(request, "Your error message")
return redirect('/')
In your html template, error message will be visible under messages variable. You can use the following snippet to display it:
{% if messages %}
<ul class="messages">
{% for message in messages %}
<li{% if message.tags %} class="{{ message.tags }}"{% endif %}>{{ message }}</li>
{% endfor %}
</ul>
{% endif %}

Is there any way to save success message in context in django

I created a model form.Is it possible to add some message in context in views.py ?
Actually i want to display a success message in template page when form is submitted and data added in database.
for example i want to do this:
if form.save:
msg = 'Data inserted successfully'
context = {'msg': msg,}
I want to save success message in my context so therefore i will show in my template page
For showing the message after model save, you can follow this Stack Over Flow Question - Django: customizing the message after a successful form save
Please this messages functionality given by django framework for onetime messages. This is the second answer provided for the above question. There are a lot of ways mentioned in the documentation that could be implemented.
Simplest one is -
In Views.py:
from django.contrib import messages
messages.add_message(request, messages.INFO, 'Data inserted successfully.')
In template:
{% if messages %}
<ul class="messages">
{% for message in messages %}
<li{% if message.tags %} class="{{ message.tags }}"{% endif %}>{{ message }}</li>
{% endfor %}
</ul>
{% endif %}

how do i delete a users message without query error?

I am having trouble with my page redirect when deleting a users comment. below is my code. It deletes the message but gives me this error: Message matching query does not exist for Message.objects.get(id=message_id).delete().
def remove_message(request, message_id):
Message.objects.get(id=message_id).delete()
return redirect(reverse('dashboard:show'))
^ABOVE FIXED:
new issue, cannot get my delete button to show when trying to delete only the current users comments. Code below:
views.py
def remove_message(request, user_id, message_id):
user = User.objects.get(id=request.session['user_id'])
Message.objects.filter(id=message_id, user = request.user).delete()
return redirect(reverse('dashboard:show', args=user_id))
show.html
{% for message in messages%}
<div class="message">
<p class='bg-primary wall_content'><strong>{{message.messageuser.first_name}} wrote:</strong></p>
<p class='wall_content'>{{message.message}}</p>
{% if message.id == request.user %}
<a href='{% url "dashboard:remove_message" user.id message.id %}'>Delete Message</a>
{% endif %}
{% for comment in comments %}
{% if message.id == comment.message.id %}
<p class='bg-success wall_content comment'><strong>{{comment.user.first_name}} wrote:</strong></p>
<p class='wall_content comment'>{{comment.comment}}</p>
{% endif %}
{% endfor %}
Instead of get, you can use filter which returns QuerySet. Unlike the get method, the filter does not raise ObjectDoesNotExist exception, but just returns a empty queryset if there's no matching object.
Deleting empty queryset has no harm.
So you the line can be replaced with:
Message.objects.filter(id=message_id).delete()

Categories

Resources