i have a simple chat application where i've customize the Authentication back end to use only the name. So far it is working and the users is logged in using Django login().
Now i have a problem with assign a user where this Error came up and cus the rest of the app to stop:
ValueError: Cannot assign "<SimpleLazyObject:
<django.contrib.auth.models.AnonymousUser
object at 0x7f7db7b71e80>>": "PChat.user" must be a "User" instance.
View.py
from chatbot import settings
from django.shortcuts import render
from django.http import HttpResponse, JsonResponse,HttpResponseRedirect
from django.views.decorators.csrf import csrf_exempt
from django.contrib.auth import authenticate, login
from Pchat.models import PChat
from django.contrib.auth.models import User
#csrf_exempt
def P_home(request):
context= locals()
template= 'P_home.html'
return render(request,template,context)
#csrf_exempt
def P_chat(request):
context= locals()
template= 'P_chat.html'
return render(request,template,context)
#csrf_exempt
def LogIIn(request):
if request.method == "POST":
name = request.POST.get('param1')
user = authenticate(username=name)
login(request, user)
return HttpResponse("OK")
#csrf_exempt
def Post(request):
if request.method == "POST":
msg = request.POST.get('param1')
if request.user.is_authenticated():
c = PChat(user=request.user, message=msg)
c.save()
return JsonResponse({ 'msg': msg, 'user': c.request.user })
else:
return HttpResponse("Account None")
models.py
from django.db import models
from django.db import models
from django.contrib.auth.models import User
class PChat(models.Model):
created = models.DateTimeField(auto_now_add=True)
user = models.ForeignKey(User)
message = models.CharField(max_length=200)
def __unicode__(self):
return self.message
auth_backend.py
from django.contrib.auth.backends import ModelBackend
from django.contrib.auth.models import User
class PasswordlessAuthBackend(ModelBackend):
"""Log in to Django without providing a password."""
def authenticate(self, username=None):
try:
return User.objects.get(username=username)
except User.DoesNotExist:
return None
def get_user(self, user_id):
try:
return User.objects.get(pk=user_id)
except User.DoesNotExist:
return None
OK, there are several errors on your code:
1) In P_home and P_chat you are using locals(), that's not recommended. You must avoid that whenever possible. You need to be explicit with data passed to the context dictionary.
2) In LogIIn view you must call login function when user is not None. [1]
3) The final error is in Post view, you must ask first wheter request.user is authenticated or not using request.user.is_authenticated() function. If the user is authenticated, then request.user is a normal User instance in other case its going to be an AnonymousUser, they both are different things. The field user in PChat model is expecting an User instead an AnonymousUser instance.
[1] https://docs.djangoproject.com/en/1.11/topics/auth/default/#how-to-log-a-user-in
You have problem in line:
c = PChat(user=request.user, message=msg)
request.user is not a User object. Firstly check request.user is actual user or not.
if request.user.is_authenticated():
c = PChat(user=request.user, message=msg)
c.save()
return JsonResponse({ 'msg': msg, 'user': c.user.username })
else:
return JsonResponse({ 'msg': 'user is not logged in' })
Edit
def Post(request):
if request.method == "POST":
msg = request.POST.get('param1')
if request.user.is_authenticated():
c = PChat(user=request.user, message=msg)
c.save()
return JsonResponse({ 'msg': msg, 'user': c.request.user })
return HttpResponse("Account None")
Related
This is my page url within the urls.py file:
path('login/',views.login_view, name="login"),
This is my page view with the views.py file:
def login_view(request):
if request.method == "POST":
user_name = request.POST.get("username")
pass_word = request.POST.get("password")
user = authenticate(request, username=user_name, password=pass_word)
# print("user1 -->", user)
if user is not None:
# print("user-->",user)
login(request, user)
return render(request, "index.html")
else:
return render(request,"http://127.0.0.1:8000/login")
else:
# return render(request, "order.html")
return render(request, "login.html")
The error I am getting is:
TypeError at /login/logincheck/login() missing 1 required positional
argument: 'user'
first create a forms.py file:
from django import forms
class LoginForm(forms.Form):
username = forms.CharField(max_length=63)
password = forms.CharField(max_length=63, widget=forms.PasswordInput)
your views.py should seem like this:
from django.contrib.auth import login, authenticate
from . import forms
def login_view(request):
form = forms.LoginForm()
message = ''
if request.method == 'POST':
form = forms.LoginForm(request.POST)
if form.is_valid():
user = authenticate(
username=form.cleaned_data['username'],
password=form.cleaned_data['password'],
)
if user is not None:
login(request, user)
message = f'Hello {user.username}! You have been logged in'
else:
message = 'Login failed!'
return render(
request, 'authentication/login.html', context={'form': form, 'message': message})
Just to add to #enes islam's approach... It's okay with what he posted as his answer but according to your project you have another view in your views.py file called login so maybe it's using that view and not the django login method you imported.
# You have this import line here
from django.contrib.auth import authenticate, logout, login
# But I noticed further down you have a defined login method
def login(request): # -> rename this method name to loginDjano or another name.
return render(request, "login.html")
That defined method is what is really being called here... So I'd suggest you delete or rename that method then go ahead and use that line again.
if user is not None:
# Remember to pass both request and user objects to this login method
login(request, user)
message = f'Hello {user.username}! You have been logged in'
else:
message = 'Login failed!'
Ideally, that should work.
I am trying to make it so that if the user already exists then log in the user else return error message. I read the documentation and implemented it into my own project. I get error: "The view sign_in.views.sign_in didn't return an HttpResponse object. It returned None instead."
from django.shortcuts import render, redirect
from .forms import SignInForm
from django.contrib.auth import authenticate, login
from django.contrib import messages
def sign_in(request):
if request.method == "POST":
form = SignInForm(request.POST)
else:
form = SignInForm()
username = request.POST.get("username")
password = request.POST.get("password")
user = authenticate(username=username, password=password)
if user is not None:
login(request, user)
return redirect("boom-home")
messages.success(request, f"Signed in as {user}")
else:
return messages.error(request, f"Failed to sign in as {user}.")
context = {
"form": form
}
return render(request, "sign_in/sign_in.html", context)
NOTE: usually this error is because people do not put "return" before the "render" method but I do put return.
I solved this problem by adding the following lines
In the following link you can see more about this problem
The view didn't return an HttpResponse object. It returned None instead
def sign_in(request):
if request.method == "POST":
form = SignInForm(request.POST)
if form.is_valid(): <---Add (Example)
return redirect('home')<---Add (Example)
else:
form = SignInForm()
I am using the django-email-verification app and I had to change how a User is signed up but I left the login authentication part the same. Every time I try to login it does not allow me to sign in and says that the credentials are wrong. Also I used emails as usernames. I'm thinking its the:
user = auth.authenticate(username=request.POST['username'], password=request.POST['password'])
that needs to be changed. Please how do I fix the login?
from django.shortcuts import render, redirect
from django.contrib.auth.models import User
from django.contrib import auth
from django.contrib.auth import get_user_model
from django_email_verification import sendConfirm
def signup(request):
if request.method == 'POST':
if request.POST['pass1'] == request.POST['pass2']:
try:
user = User.objects.get(username=request.POST['username'])
return render(request, 'accounts/signup.html', {'error': 'Email is already registered'})
except User.DoesNotExist:
'''user = User.objects.create_user(request.POST['username'], password=request.POST['pass1'])
auth.login(request, user)'''
user = get_user_model().objects.create(username=request.POST['username'], password=request.POST['pass1'], email=request.POST['username'])
sendConfirm(user)
return redirect('home')
else:
return render(request, 'accounts/signup.html', {'error': 'Passwords must match'})
else:
return render(request, 'accounts/signup.html')
def login(request):
if request.method == 'POST':
user = auth.authenticate(username=request.POST['username'], password=request.POST['password'])
if user is not None:
auth.login(request, user)
return redirect('home')
else:
return render(request, 'accounts/login.html',{'error':'username or password is incorrect.'})
else:
return render(request, 'accounts/login.html')
def logout(request):
if request.method == 'POST':
auth.logout(request)
return redirect('home')
The problem is not with authenticating, but with creating the user. Passwords are normally hashed. The .create(…) function [Django-doc] will not hash these, you can make use of .create_user(…) [Django-doc] instead:
user = get_user_model().objects.create_user(
username=request.POST['username'],
password=request.POST['pass1'],
email=request.POST['username']
)
The .create_user(…) function is a function the manager of the user model normally should provide. This will for (most) user models store the hash of the password in the database.
I have my API and here I developed login and logout view. Now I want to write pytests and I have a problem, idk how to create fixture where I can make my user authorized and set some id in session(this is required for the logout).
I create new_user via fixture(to avoid working with my db).
views
#csrf_exempt
def login(request):
if request.method == "POST":
data = json.loads(request.body.decode('utf-8'))
if not is_data_valid_for_login(data):
return HttpResponseBadRequest()
user = authenticate(email=data["email"], password=data["password"])
if user:
auth_login(request, user)
response = HttpResponse(status=200, content_type='application/json')
request.session['id'] = user.id
return response
return HttpResponseBadRequest()
return HttpResponseBadRequest()
#csrf_exempt
def logout(request):
if request.method == "GET":
auth_logout(request)
response = HttpResponse(status=200)
if 'id' in request.session:
del request.session['id']
return response
return HttpResponseBadRequest
pytest
import pytest
from user.models import User
PASSWORD = "testPassword"
#pytest.fixture()
def user():
return User.create(first_name="Name", last_name="Last", email="test#test.com", password=PASSWORD)
I am now working on a system using the Django framework. I am writing the user login part. It seems successful but it doesn't work very well.
The login system can recognise the user by his/her username and password.
The authentication could only last for one "webpage". When I loaded another page or even reloaded the page, django can't get the info of the user(seems logged out)
If I looked at the page resources, I saw a session number made after the login process.
What should I do to ensure only one login is needed? And keep my user logged in during the whole process?
Here is my view file
from django.shortcuts import render
from django.http import HttpResponse,HttpResponseRedirect
from django.template import RequestContext, loader
from django.shortcuts import render
from django.contrib.auth.decorators import login_required
from django.contrib.auth import authenticate, login, logout
from django.shortcuts import render_to_response,redirect
from django.template import RequestContext
from django.views.decorators.csrf import csrf_exempt
from django.template.context_processors import csrf
from . import models
from . import form as f
from django.contrib.sessions.backends.db import SessionStore
def index(request):
if request.user != None :
template = loader.get_template('index.html')
return HttpResponse(template.render(None))
else :
return HttpResponseRedirect('/PDT/login_failed')
def Home(request):
template = loader.get_template('Home.html')
return HttpResponse(template.render(None))
def loggin_in(request):
c = {}
c.update(csrf(request))
return render_to_response('login.html', c)
def login_user(request):
logout(request)
username = password = ''
if request.POST:
username = request.POST.get('username','')
password = request.POST.get('password','')
user = authenticate(username=username, password=password)
if user is not None:
if user.is_active:
login(request, user)
request.session['username']=user.username
return HttpResponseRedirect('/PDT/logged_successful')
return HttpResponseRedirect('/PDT/inactive')
return HttpResponseRedirect('/PDT/incorrect')
return HttpResponseRedirect('/PDT/login_failed')
def logged_in(request):
if request.user :
return render_to_response('index.html',{ 'user' : request.user },context_instance=RequestContext(request))
else :
return HttpResponseRedirect('/PDT/login_failed')
def login_failed(request):
return render_to_response('problem.html',{ 'message' : "Login failed" })
def log_out(request):
request.session.flush()
logout(request)
return render_to_response('problem.html',{ 'message' : "Logged out" })
def inactive(request):
return render_to_response('problem.html',{ 'message' : "Inactive" })
def incorrect(request):
return render_to_response('problem.html',{ 'message' : "Incorrect Username or Password" })
def iter_update(request):
if request.session['username'] != None :
return render_to_response('iter_update.html',{ 'user' : request.user },context_instance=RequestContext(request))
else :
return HttpResponseRedirect('/PDT/login_failed')
def Create_form(request):
if request.method == "POST":
form = f.ProjectForm(request.POST)
if(form.is_valid()):
print(request.POST['title'])
form.save()
message = 'success'
else:
message = 'fail'
return render_to_response('Create_form.html',
{'message': message,
'user': request.user,},
context_instance=RequestContext(request))
else:
return render_to_response('Create_form.html',
{'form': f.ProjectForm()},
context_instance=RequestContext(request))
Please use return render(request, template_name, context_dict) to render templates. Your peculiar way probably strips it of context.
Also, take a look at this decorator, and use it instead of your current if request.user != None : statements.
Your user is logged in, but because you are strangely rendering the Home and Index templates via template.render(None), there is no request or user context in your template. Instead, use the render shortcut which runs context processors.