django - KeyError when trying to log in - django

when i try to login it shows :
KeyError at /admin/
'loggedin'
it shows this error only when i submit with correct username and pwd. so i think it is about my admin view..
here is my log in view :
def log_user_in(request):
if request.method=='POST':
uname = request.POST['username']
password = request.POST['password']
user = authenticate(username=uname, password=password)
form = LoginForm(request.POST)
if form.is_valid():
if user is not None:
request.session['loggedin']="djangoo"
login(request, user)
return HttpResponseRedirect('/admin/')
else:
form = LoginForm()
return render_to_response('login.html',{'form':form,},context_instance=RequestContext(request))
and log out view :
def log_user_out(request):
user = request.user
try:
del request.session['loggedin']
except KeyError:
pass
logout(request)
return HttpResponseRedirect('/blog/%s/'%(user))
and admin view :
def admin_view(request):
if request.session['loggedin'] == "djangoo":
#other codes..
here is my urls.py:
urlpatterns = patterns('blog.views',
url(r'^superadmin/', include(admin.site.urls)),
url(r'^blog/(?P<username>[-\w]+)/$',view='index', name='index'),
url(r'^blog/(?P<username>[-\w]+)/post/(?P<postslug>[-\w]+)',view='single_post', name='view_blog_post'),
url(r'^login/$', view='log_user_in'), # i log in to admin page from this url
url(r'^admin/$', view='admin_view', name='admin'),# to this url
url(r'^admin/logout/$', view='log_user_out', name='logout'),
url(r'^admin/post/add/$', view='add_post',name='addpost'),
url(r'^admin/post/edit/(?P<post_id>\d+)', view='edit_post', name='editpost'),
url(r'^admin/post/delete/(?P<post_id>\d+)', view='delete_post', name='deletePost'),
)

When you logged out, you manually delete request.session['loggedin'] key, and when you browse to admin page, request.session['loggedin'] fails because you already delete that key.
You can control if request.session has loggedin key with:
`loggedin` in request.session
So, writing your admin view like:
def admin_view(request):
if `loggedin` in request.session and request.session['loggedin'] == "djangoo":
#other codes..
Or simply use
if request.session.get('loggedin') == 'djangoo'
as #Alexander Larikov said
EDIT: I need to mention that, it is good to check if a key exists in dictionary or dictionary-like structure, especially if you also may delete that key in somewhere else.

Related

DJango - NoReverseMatch Error - What is wrong?

I am trying to set up a user password change from built on this tutorial. Unfortunately, on success, this tutorial just returns the user to the change password form, which doesn't seem very satisfactory. So, I am attempting to redirect the user user to a success template.
My code is in an app called your_harmony
base.py
INSTALLED_APPS = [
...
'your_harmony',
...
]
urls.py
urlpatterns = [
...
url(r'^your-harmony/', include('your_harmony.urls')),
...
]
your_harmony/urls.py
urlpatterns = [
url(r'password/$', change_password, name='change_password'),
url(r'password_changed/$', password_changed, name='password_changed'),
]
views.py
def change_password(request):
if request.method == 'POST':
form = PasswordChangeForm(request.user, request.POST)
if form.is_valid():
user = form.save()
update_session_auth_hash(request, user) # Important!
messages.success(request, 'Your password was successfully updated!')
return redirect('password_changed')
else:
messages.error(request, 'Please correct the error below.')
else:
form = PasswordChangeForm(request.user)
url = 'registration/change_password.html'
return render(request, url, {'form': form})
def password_changed(request):
url = 'password_changed.html'
return render(request, url, {})
When I use the form to change the password and submit, the password is changed correctly, but I get the error
NoReverseMatch at /your-harmony/password_changed/
However, when I hover over the link to call the change password form, the url displayed in the browser is
127.0.0.1:8000/your-harmony/password
Can someone please point what I am doing wrong?
You can use this
from django.urls import reverse
return redirect(reverse('password_changed'))
after your success
and in your urls.py
from . import views
urlpatterns = [
url(r'password/$', views.change_password, name='change_password'),
url(r'password_changed/$', views.password_changed, name='password_changed'),
]
You should use namespaces
include('your_harmony.urls', namespace='whatever')
...
def f():
return redirect(reverse('whatever:password_changed'))

Problems with Django logout on URLs

I'm beginner with Django and I've resolved my problem yet, but I want to understand...
I've a login page on my app and a logout page, here is it:
urls.py:
url('deconnexion', views.logout, name='deconnexion'),
url('connexion', views.connexion, name='connexion'),
views.py:
def connexion(request):
error = False
if request.method == "POST":
form = ConnexionForm(request.POST)
if form.is_valid():
username = form.cleaned_data["username"]
password = form.cleaned_data["password"]
user = authenticate(username=username, password=password)
if user:
login(request, user)
else:
error = True
else:
form = ConnexionForm()
return render(request, 'dashboard/connexion.html', locals())
#login_required(login_url='/dashboard/connexion/')
def logout(request):
django_logout(request)
return redirect(reverse(connexion))
If I change place for url: connexion in place of deconnexion, my script doesn't work... I don't logout me and I'm redirected on the connexion page which is being connected...
If somebody have an idea?
P.S.: Sorry for my poor English, I'm French... And French with English.... we all know it's complicated... sorry ;)
As described in django documentations you can do like this:
from django.contrib.auth import logout
def logout_view(request):
logout(request)
return redirect(reverse(connexion))

python - Django redirect to next after login (Generic Form View)

I am using generic form view for authentication, I am getting next parameter in url but unfortunately I don't know how to redirect it to next, after successful login for Generic Form View, here is my view
class LoginView(
views.AnonymousRequiredMixin,
generic.FormView):
form_class = LoginForm
success_url = reverse_lazy('home')
template_name = 'accounts/registered/login.html'
def form_valid(self, form):
username = form.cleaned_data['username']
password = form.cleaned_data['password']
user = authenticate(username=username, password=password)
if user is not None and user.is_active and user.is_seller:
login(self.request, user)
return super(LoginView, self).form_valid(form)
else:
return self.form_invalid(form)
I am getting this
http://127.0.0.1:8000/accounts/login/?next=/accounts/dashboard/
help me out!
So essentially, what the url that you are getting means is that it's trying to go to 127.0.0.1:8000/accounts/dashboard/, but because the user needs to be logged in, it's going to the login page first. Essentially, this means that your view is not logging the user in for some reason.
Try using (or extending) Django's built in LoginForm class (https://docs.djangoproject.com/en/2.0/topics/auth/default/#django.contrib.auth.views.LoginView)
Alternatively, go with a broader solution suite, such as django allauth (https://github.com/pennersr/django-allauth/blob/master/docs/index.rst)
You should use HttpRedirectResponse:
views.py
from django.http import HttpResponseRedirect
def login(request):
# You logic goes here
return HttpResponseRedirect('dashboard')
def dashboard(request):
context = {
# User information goes here
}
return render(request, 'dashboard', context)
Do not forget to add this call to the login method in your urls.py:
path('login', views.login, name='login'),
path('dashboard', views.dashboard, name='dashboard'),
You should also take a look at https://docs.djangoproject.com/en/2.0/ref/request-response/ for a better understanding of how request and response work.
You should also be familiar with https://docs.djangoproject.com/en/2.0/intro/tutorial04/ so that you could understand an example of HttpResponseRedirect.

Django - First time viewers sometimes are shown a login_required page

While showing my website to people, I have noticed that sometimes, when viewing the website for the first time, the wrong page is displayed.
views.py
from django.contrib.auth.decorators import login_required
def index(request):
if request.user.is_authenticated():
return HttpResponseRedirect('/home/')
else:
return render(request, 'free/landing_page.html')
#login_required
def home(request):
...
def login_user(request):
if request.method == 'POST':
username = request.POST['username']
password = request.POST['password']
user = authenticate(username=username, password=password)
if user is not None and user.is_active:
login(request, user)
return HttpResponseRedirect("/home/")
else:
errors = "True"
return render(request, 'registration/login.html', {'errors': errors})
else:
return render(request, 'registration/login.html')
and
urls.py
url(r'^$', views.index, name="index"),
url(r'^home/$', views.home, name="home"),
The idea is to have the home page displayed, if a user already has an account and is authenticated. And if the user is not authenticated then the landing page should be displayed.
So here we go, What I have noticed, is a first time viewer of the website sees the home page rather than the landing page, and to make it even worse, the home page is populated with information from another user's account. From here, if you click on any link you are redirected back to the landing page where you can properly create an account or login. It is strange because the few times this has happened it is on a computer that has never even visited the site before.
I do have LOGIN_REDIRECT_URL = '/home/' in my settings.py which I am thinking of removing, because of the return HttpResponseRedirect("/home/") in my user_login function.
Has anyone ever ran into this before?

#login_required not working as expected in Django?

I find #login_required very useful. I have used this #login_required(login_url='/login/') before each views. If the user tries to access /upload url it redirects to url as: http://127.0.0.1:8000/login/?next=/upload_file/ My urls are very simple:
urlpatterns = patterns('',
#url(r'^admin/', include(admin.site.urls)),
url(r'^upload_file/', 'fileupload.views.upload_file'),
url(r'^show_file/', 'fileupload.views.show_list'),
url(r'^sync/', 'fileupload.views.sync'),
url(r'^login/', 'fileupload.views.login_user'),
url(r'^upload_file_form', 'fileupload.views.upload_file_form' )
)
Now when the user presses login the page is redirected to nowhere. I am sure my url pattern is not correct. What am I missing? Thanks
Edit:
def login_user(request):
errors = []
state = "LOG IN"
username = password = ''
if request.method == 'POST':
username = request.POST['username']
password = request.POST['password']
user = authenticate(username='username', password='password')
if user is not None:
if user.is_active:
login(request, user)
state = "You're successfully logged in!"
else:
state = "Your account is not active, please contact the site admin."
else:
state = "Your username and/or password were incorrect."
return render_to_response('login.html', {'state':state, 'username': username}, context_instance=RequestContext(request))
Your fileupload.views.login_user view needs to honor the next querystring parameter itself. This is built-in to Django's login view, but since you have rolled your own, you'll need to implement that functionality yourself.