Redirecting when passing a message in django
I am trying to trigger a redirect after I have checked if a user_settings
user exists (if they do not exist - the user is submitted to the form to be entered and saved).
I want to redirect the user to the appropriate form and give them a message that they need to "save their settings" so they know why they are being redirected.
The function looks like this:
def trip_email(request):
try:
user_settings = Settings.objects.get(user_id=request.user.id)
except Exception as e:
messages.error(request, 'Please save your settings before you print mileage!')
return redirect('user_settings')
This function checks user preferences and redirects me accordingly - but the message never appears at the top of the template.
You might be thinking at first, "Are the messages configured correctly in your Django?"
I have other functionality where I use messages that are not redirects, the messages are displayed as expected in the template without issue. The messages are integrated into my template as appropriate and work.
It is only when I use redirect
that I cannot see the messages that I am sending.
If I use render
like below I see a message (but of course the url doesn't change) which is what I would like to do.
def trip_email(request):
try:
user_settings = Settings.objects.get(user_id=request.user.id)
except Exception as e:
messages.error(request, 'Please save your settings before you print mileage!')
form = UserSettingsForm(request.POST or None)
return render(request, 'user/settings.html', {'form': form})
I have a couple of other places where I need to use redirect
because it functionally makes sense to do it, but I also want to pass messages to these redirects.
The function user_settings
looks like this:
def user_settings(request):
try:
user_settings = Settings.objects.get(user_id=request.user.id)
form = UserSettingsForm(request.POST or None, instance=user_settings)
except Settings.DoesNotExist:
form = UserSettingsForm(request.POST or None)
if request.method == 'POST':
settings = form.save(commit=False)
settings.user = request.user
settings.save()
messages.warning(request, 'Your settings have been saved!')
return render(request, 'user/settings.html', {'form': form})
I can't find anything in the documentation that says you can't send forward messages ... but I can't figure out how to show them.
Edit: This is how I handle the messages in the template:
{% for message in messages %}
<div class="alert {{ message.tags }} alert-dismissible" role="alert">
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
{{ message }}
</div>
{% endfor %}
I'm not sure if this matters, but it looks like it was calling "GET" almost twice.
the url section looks like this for these two urls:
# ex: /trips/email
url(r'^trips/email/$', views.trip_email, name='trip_email'),
# ex: /user/settings
url(r'^user/settings/$', views.user_settings, name='user_settings'),
source to share
You cannot view the error message because it is not being processed and hence the message has nowhere to go. The best way to do something like this is to display an intermediate page that will display an error message and redirect after a timeout, something like the sort used by payment gateways and redirecting you to your bank.
You can do something like this:
def trip_email(request):
try:
user_settings = Settings.objects.get(user_id=request.user.id)
except Exception as e:
return render(request, 'no_setting_error.html', {'form': form})
and in the no_setting_error
html page insert Javscript to auto redirect after timeout like:
<script>
function redirect(){
window.location.href = "/user_settings";
}
setTimeout(redirect, 3000);
</script>
This will automatically redirect you from the error page to the page user_settings
after 3 seconds.
Hope this helps!
source to share
No, I think the best way is to use your sessions.
from django.contrib import posts <<this is optional if you choose to use django messaging
Handle your form
def handle_form(request):
...
request.session['form_message'] = "success or fail message here"
redirect('/destination/', {})
def page_to_render_errors():
...
message = None
if( 'form_message' in request.session ):
message = request.session['form_message']
del request.session['form_message']
messages.success = (request, message ) #<< if you choose to pass it through django messaging
render(request,'template_name.html', {'message_disp':message })
If you had a better way, it pushed me. Happy coding!
source to share