I have a site, that has a submit form, but one must be logged in for that. And if the user is not logged in, it redirects it to the login page. And this all fine. My question is, what do I do to display the error message, "You must be logged to submit.", if the user is not logged in and tries to submit the form, but has to display the normal login page if not.
Thank you.
You might want to use decorator #login_required:
from django.contrib.auth.decorators import login_required
#login_required(login_url='/your/login/url')
def your_view(request):
# your view code here
Hope this helps.
Related
I want to allow a user to delete his account and upon deletion, I want the user to be logged out and see a html page account_deleted.html for confirmation.
students/views.py:
def delete_account(request):
user = User.objects.get(username=request.user)
user.delete()
context = {
"deleted_msg": "Account has been deleted",
}
return render(request, "students/account_deleted.html", context) and redirect("students:logout")
For logout, I'm using the built-in LogoutView function. The logout redirect URL in my settings.py is set to my home page.
students/urls.py:
path('logout/', LogoutView.as_view(), name='logout'),
In case of an account deletion, how can I make the delete_account(request) function return a render and redirect at the same time? Is that even possible?
Thanks!
You can log the user out before deleting the account by placing logout(request) before your user.delete() line. You will need to import it with from django.contrib.auth import logout.
As Bruno said in his answer, using a redirect instead of render is preferable after a POST request, and you should update your view to only respond to POST requests.
If you are having trouble with your website crashing after a user is deleted, make sure you are using the proper access control in all your views, eg by using the #login_required decorator or the equivalent mixin on all views that require a user to be logged in. If you do this the user will just be redirected to the login page if he or she is not logged in instead of crashing your site.
First things firsts: your view should 1/ only accept logged in users and 2/ only accept POST requests (you definitely dont want a GET request to delete anything from your database). Also, this:
User.objects.filter(username=request.user)
is useless - you already have the current user in request.user - and potentially dangerous if your auth backend allows for duplicated usernames.
and this:
return render(request, "students/account_deleted.html", context) and redirect("students:logout")
is of course plain wrong. A view returns one single HTTP response, you can't return two (it wouldn't make any sense), and you can't "and" two responses together (well, you can but the result is certainly not what you expect - read the FineManual about the and operator).
The proper solution is to 1/ manually log out the user (cf voodoo-burger's answer), 2/ use the messages framework to inform the user her accont has been deleted, and 3/ redirect to the home page (you ALWAYS want to redirect after a successful post, cf https://en.wikipedia.org/wiki/Post/Redirect/Get for the why).
I am trying to write a basic website in django. I need the user (i'm still using the default one) to be able to login, logout, register, etc. I have the basic functionality set up, but I want the user to be able to visit a profile page where it will display basic information about the user. Naturally, the profile page must use the login_required decorator but the way I have it set up now is that once anybody signs in they can see any profile page.
Part of the URL file:
url(r'^profile/(?P<username>[\w.#+-]+)/$',
login_required(ProfilePageView.as_view())),
As you can see, the url should consist of "profile/" follow by the username of the user. How can I set it up so that only the user with the username following the "profile/" part of the url can see that page. With this code some user could login with any username and then just change the url and resend the get request.
You can do something like this. if you have created a Profile model for each user you can also access the Profile information using profile_info=request.user.profile
def login_user(request):
username=request.POST.get('username','')
password=request.POST.get('password','')
user=auth.authenticate(username=username,password=password)
if user is not None:
auth.login(request,user)
return HttpResponseRedirect('/loggin/')
else:
return HttpResponseRedirect('/invalid/')
def loggin(request):
username=None
if request.user.is_authenticated:
#profile_info=request.user.profile
info=request.user
return render(request,'base.html',locals())
<head>
<body>
<h5>{{info.first_name}}{{info.first_name}}</h5>
</body>
</head>
The admin app in django has this behaviour, and I want to replicate it in my project.
In the admin, once you login and press the browser back button, shows the home page again, and the it does not let you go back any further.
It doesn't seem it uses javascript.
Any ideas how to accomplish this?
Thanks.
My code
def login_user(request):
if request.user.is_authenticated:
return redirect(reverse('sinapsis-home'))
else:
...# code processing the authentication
# the redirect
return redirect(reverse('sinapsis-home'))
The solution is partially the proposed answer, but adding a cache decorator.
It is not javascript, and it was so easy to prove just disabling javascript in the browser. I was slow on that point.
As you navigate the browser back and for, the cached page does not load again, that's why you can go back, in this case, to the login page even if you are logged in. I think this behaviour is prone to problems, for example a csrf error. I repeat, not permitting the user go back to the login page once logged in is a standard behaviour of web apps, including the django admin.
So the solution to this problem is adding to the login view a redirect if the user is logged in and a never_cache decorator:
from django.views.decorators.cache import never_cache
#never_cache
def login_user(request):
...
if user.is_authenticated:
return HttpResponseRedirect(reverse('my_redirect'))
...
Well, Like you said that isn't js, It's as simple as an if conditional like:
if not request.user.is_authenticated:
# Return a login form to login
else:
return redirect('success:page')
Edit:
After add your code, the problem was that you were using request.user.is_autenticated() with parentheses and it was deprecated in Django 1.10 more information
I want to be able to automatically log users out when they leave my Django site. Not just when they close the browser, but whenever they navigate away to a different site. Is this possible?
I'm displaying sensitive data to the user, and if they were to go to a new URL, and then hit the back button, I don't want the sensitive data displayed. I want them to be forced to log back in.
Is this possible? Or is this something I would have to do on the front end?
Check out this answer on how to detect when a visitor moves away from the page.
Documentation: Page Visibility API
Logout user via Ajax:
from django.views.generic import View
from django.http import JsonResponse
from django.contrib.auth import logout
class LogoutView(View):
"""
The logout view class. This will log the user out and invalidate the session.
"""
def post(self, *args, **kwargs):
logout(self.request)
return JsonResponse({'success': True}, **kwargs)
If you only want to 'logout' user if they leave the page, try hooking into onbeforeunload event.
$(window).unload(function () {
/* login for ajax call goes here */
});
WindowEventHandlers.onbeforeunload
What I want is to redirect the user to a specific page when they log in if a flag is raised. So I know that all of the login requests go through django.contrib.auth.views.login. Do I have to modify this to accomplish what I want to do or is there some other way to do this. So when I log in I hit the index page and that's fine, I can work with that but what if the user tries to access a page where log in is required. Here's what it will look like
login/?next=/page_that_requires_login
so now after login, it will not hit the index page anymore, it will go directly to page_that_requires_login. I am a little new to django but my instinct tells me that I shouldn't have to check this flag on every page. Is there a common place that I can do some code logic after a user is logged in no matter what page they get redirect to?
Django provides decorator called, login_required() which we can attach to any view, where we require the user to be logged in. If a user is not logged in and they try to access a page which calls that view, then the user is redirected to another page which you can set, typically the login page.The following is an example code for a view called restricted.
#login_required
def restricted(request):
return HttpResponse("since you are logged in you can see this page)
Note that to use a decorator, you place it directly above the function signature, and put a # before naming the decorator. Python will execute the decorator before executing the code of your function/method. To use the decorator you will have to import it, so also add the following import:
from django.contrib.auth.decorators import login_required
To set a page to which the user is redirected if he is not logged in, you need to add the something like this to settings.py
LOGIN_URL = "/app_name/login/"
This ensures that the login_required() decorator will redirect any user not logged in to the URL /app_name/login/.
I redirected by groupwise as :
from django.http import HttpResponseRedirect
def loggedin_view(request):
usergroup = None
if request.user.is_authenticated():
usergroup = request.user.groups.values_list('name', flat=True).first()
if usergroup == "staffGroup":
return HttpResponseRedirect("/cmit/userDash")
elif usergroup == "supervisorGroup":
return HttpResponseRedirect("/cmit/supervisorDash")
elif usergroup == "auditGroup":
return HttpResponseRedirect("/cmit/auditDash")
elif usergroup == "mgtGroup":
return HttpResponseRedirect("/cmit/mgtDash")
else:
return HttpResponseRedirect("/admin/")