NotImplementedError: Django doesn't provide a DB representation for AnonymousUser - python

I get the following error:
Traceback:
File "C:\Users\HP\GST\lib\site-packages\django\core\handlers\exception.py"
in inner
35. response = get_response(request)
File "C:\Users\HP\GST\lib\site-packages\django\core\handlers\base.py" in
_get_response
128. response = self.process_exception_by_middleware(e,
request)
File "C:\Users\HP\GST\lib\site-packages\django\core\handlers\base.py" in
_get_response
126. response = wrapped_callback(request, *callback_args,
**callback_kwargs)
File "C:\Users\HP\Desktop\erpcloud\accounts\views.py" in change_password
31. if form.is_valid():
File "C:\Users\HP\GST\lib\site-packages\django\forms\forms.py" in is_valid
179. return self.is_bound and not self.errors
File "C:\Users\HP\GST\lib\site-packages\django\forms\forms.py" in errors
174. self.full_clean()
File "C:\Users\HP\GST\lib\site-packages\django\forms\forms.py" in
full_clean
376. self._clean_fields()
File "C:\Users\HP\GST\lib\site-packages\django\forms\forms.py" in
_clean_fields
397. value = getattr(self, 'clean_%s' % name)()
File "C:\Users\HP\GST\lib\site-packages\django\contrib\auth\forms.py" in
clean_old_password
366. if not self.user.check_password(old_password):
File "C:\Users\HP\GST\lib\site-packages\django\contrib\auth\models.py" in
check_password
396. raise NotImplementedError("Django doesn't provide a DB
representation for AnonymousUser.")
Exception Type: NotImplementedError at /accounts/change-password/
Exception Value: Django doesn't provide a DB representation for
AnonymousUser.
My view looks like this:
def change_password(request):
if request.method == 'POST':
form = PasswordChangeForm(data=request.POST, user=request.user)
if form.is_valid():
form.save()
update_session_auth_hash(request, user)
return redirect(reverse('company:Dashboard'))
else:
return redirect(reverse('accounts:change_password'))
else:
form = PasswordChangeForm(user=request.user)
args = {'form': form}
return render(request, 'accounts/change_password.html', args)
Firstly, I thought that this was due to the fact that I didn't have Django updated, but now I have, and I receive the same error.
I've looked at some solutions that other users asked, but none applied in my case
Any help, please ?

There is nothing wrong with the view itself. The problem is that if a user is not logged in, then request.user will point to a AnonymousUser object. You can see it as a virtual user. This user however has no database representation, since we do not know anything about the user. It is more used to provide a uniform interface.
Now since request.user is an AnonymousUser, you aim to change the password of that user, but you can not store that into a database, hence the error.
The user thus first needs to log in, then request.user will be a real user, and updating the password should work.
I advise however to add a #login_required decorator to the view to prevent this scenario from happening:
from django.contrib.auth.decorators import login_required
#login_required
def change_password(request):
if request.method == 'POST':
form = PasswordChangeForm(data=request.POST, user=request.user)
if form.is_valid():
form.save()
update_session_auth_hash(request, user)
return redirect(reverse('company:Dashboard'))
else:
return redirect(reverse('accounts:change_password'))
else:
form = PasswordChangeForm(user=request.user)
args = {'form': form}
return render(request, 'accounts/change_password.html', args)

Related

django-tenants: redirecting to tenant url after login raises "NoReverseMatch: 'demo.localhost' is not a registered namespace"

I don't seem to find a way to solve an error happening at the user authentication.
User needs to login at the public website level let's say localhost/login and when he/she is authenticated, I need the user to be redirected in the corresponding sub domain, for example demo.localhost. This is not working for me so far, even after checking some posts about the subject.
Here is the views.py in customers.views where user log in:
def login_view(request):
if request.method == 'POST':
form = AuthenticationForm(request,data=request.POST)
print("form login view")
if form.is_valid():
print("checkpoint")
username = form.cleaned_data.get('username')
password = form.cleaned_data.get('password')
user = authenticate(username=username, password=password)
user = form.get_user()
schema_name = user.schema_name
print(user)
if user is not None:
login(request, user)
url = reverse(schema_name + '.localhost:8000/mydashboard/')
print("url")
return HttpResponseRedirect(url)
else:
print("not working")
form = AuthenticationForm()
context = {
'form': form,
}
return render(request, 'login.html', context)
here is what urls in the core folder:
urlpatterns = [
path('admin/', admin.site.urls),
path('django_plotly_dash/', include('django_plotly_dash.urls')),
path('mydashboard/', include('mydashboard.urls',namespace="mydashboard")),
]
and I have added app_name = 'mydashboard' in mydashboard.urls
Here is the traceback of the error I keep getting:
Internal Server Error: /registration/loginUser
Traceback (most recent call last):
File "/Users/pierre/opt/anaconda3/lib/python3.9/site-packages/django/urls/base.py", line 71, in reverse
extra, resolver = resolver.namespace_dict[ns]
KeyError: 'demo.localhost'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/Users/pierre/opt/anaconda3/lib/python3.9/site-packages/django/core/handlers/exception.py", line 47, in inner
response = get_response(request)
File "/Users/pierre/opt/anaconda3/lib/python3.9/site-packages/django/core/handlers/base.py", line 181, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/Users/pierre/Desktop/simulation_application/customers/views.py", line 65, in login_view
url = reverse(schema_name + '.localhost:8000/mydashboard/')
File "/Users/pierre/opt/anaconda3/lib/python3.9/site-packages/django/urls/base.py", line 82, in reverse
raise NoReverseMatch("%s is not a registered namespace" % key)
django.urls.exceptions.NoReverseMatch: 'demo.localhost' is not a registered namespace
UPDATE:
Remove the reverse and included request.scheme in the url.
def login_view(request):
if request.method == 'POST':
form = AuthenticationForm(request,data=request.POST)
print("form login view")
if form.is_valid():
print("checkpoint")
username = form.cleaned_data.get('username')
password = form.cleaned_data.get('password')
user = authenticate(username=username, password=password)
user = form.get_user()
schema_name = user.schema_name
print(user)
if user is not None:
login(request, user)
print(request.scheme)
url = request.scheme + '://' + schema_name + '.localhost:8000/mydashboard/'
print("url",url)
return HttpResponseRedirect(url)
else:
print("not working")
form = AuthenticationForm()
context = {
'form': form,
}
return render(request, 'login.html', context)
this is still working and output the following error:
response = get_response(request) …
Local vars
/Users/pierre/opt/anaconda3/lib/python3.9/site-packages/django/core/handlers/base.py, line 181, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs) …
Local vars
/Users/pierre/opt/anaconda3/lib/python3.9/site-packages/django/contrib/auth/decorators.py, line 32, in _wrapped_view
return redirect_to_login( …
Local vars
/Users/pierre/opt/anaconda3/lib/python3.9/site-packages/django/contrib/auth/views.py, line 190, in redirect_to_login
return HttpResponseRedirect(urlunparse(login_url_parts)) …
Local vars
/Users/pierre/opt/anaconda3/lib/python3.9/site-packages/django/http/response.py, line 507, in __init__
raise DisallowedRedirect("Unsafe redirect to URL with protocol '%s'" % parsed.scheme) …
Local vars
Unsafe redirect to URL with protocol 'localhost'
Bad Request: /mydashboard/simulations_list
HTTP GET /mydashboard/simulations_list 400 [0.09, 127.0.0.1:50218]
This is strange because the requested url is perfectly working url, registered and accessible without a problem before trying to redirect to it after the login
EDIT #2:
Found out that the above code works when the target url does not require login required
# this does not work
#login_required
def simulationslistView(request,):
return render(request, 'simulations_list.html')
# this works
def simulationslistView(request,):
return render(request, 'simulations_list.html')
I am obviously make sure that the app is secured and can only be accessed by logged in users. Is there a work around to make sure it works?
reverse is an internal django utility to go from "app name" + ':' + "url friendly name" to "real url". In your example, you're already providing the "real url".
Quit while you're ahead and just do:
if user is not None:
login(request, user)
url = request.scheme + '://' + schema_name + '.localhost:8000/mydashboard/'
print("url")
return HttpResponseRedirect(url)
Notice no reverse
Notice the adding of the URL scheme (http/https determined by how the request was originally made)

Django Form is_valid() missing 1 required positional argument: 'self'

I am trying to create a form(boqform) to post data into a model(boqmodel)
but I am getting this
typeerror is_valid() missing 1 required positional argument: 'self'
I need to display a form called boqform on html template and post the data user entered into boqmodel
my view:
def boqmodel1(request):
if boqform.is_valid():
form = boqform(request.POST)
obj=form.save(commit=False)
obj.save()
context = {'form': form}
return render(request, 'create.html', context)
else:
context = {'error': 'The post has been successfully created. Please enter boq'}
return render(request, 'create.html', context)
Traceback:
File "C:\Users\TRICON\AppData\Local\Programs\Python\Python38-32\lib\site-packages\django\core\handlers\exception.py" in inner
34. response = get_response(request)
File "C:\Users\TRICON\AppData\Local\Programs\Python\Python38-32\lib\site-packages\django\core\handlers\base.py" in _get_response
115. response = self.process_exception_by_middleware(e, request)
File "C:\Users\TRICON\AppData\Local\Programs\Python\Python38-32\lib\site-packages\django\core\handlers\base.py" in _get_response
113. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Users\TRICON\Desktop\ind\ind\boq\views.py" in boqmodel1
23. if boqform.is_valid():
Exception Type: TypeError at /boq/create/
Exception Value: is_valid() missing 1 required positional argument: 'self'
You're trying to call the instance function is_valid() on the class boqform. You need to get an instance of boqform first. Switching lines 1 and 2 of the function should fix the issue:
def boqmodel1(request):
form = boqform(request.POST)
if form.is_valid():
obj=form.save(commit=False)
obj.save()
context = {'form': form}
return render(request, 'create.html', context)
else:
context = {'error': 'The post has been successfully created. Please enter boq'}
return render(request, 'create.html', context)

How to solve a attribute error in Django?

I am trying to log in a user but I am getting an attribute error.
Here is my forms.py:
class Login(forms.Form):
email = forms.EmailField(max_length=250)
password = forms.CharField(widget=forms.PasswordInput)
def login_user(self):
email = self.cleaned_data['email']
password = self.cleaned_data.get('password')
user = authenticate(email=email, password=password)
if user in User.objects.all():
login(self, user)
else:
return render(self, 'todoapp/waiting_2.html')
Here is my views.py:
def login_user(request):
if request.method == 'POST':
login_form = Login(request.POST)
if login_form.is_valid():
login_form.login_user()
login_form.save()
return HttpResponseRedirect(reverse('dashboard'))
else:
return render(request, 'todoapp/waiting_2.html')
return render(request, 'registration/login.html', {'form': Login()})
When I fill in the fields and try to log in, I am getting the error:
AttributeError at /login/
'Login' object has no attribute 'session'
Traceback:
File "/home/gblp250/PycharmProjects/practice/venv/local/lib/python2.7/site-packages/django/core/handlers/exception.py" in inner
41. response = get_response(request)
File "/home/gblp250/PycharmProjects/practice/venv/local/lib/python2.7/site-packages/django/core/handlers/base.py" in _get_response
187. response = self.process_exception_by_middleware(e, request)
File "/home/gblp250/PycharmProjects/practice/venv/local/lib/python2.7/site-packages/django/core/handlers/base.py" in _get_response
185. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/home/gblp250/PycharmProjects/assignment/todoapp/views.py" in login_user
48. login_form.login_user(request)
File "/home/gblp250/PycharmProjects/assignment/todoapp/forms.py" in login_user
27. login(self, request, user)
File "/home/gblp250/PycharmProjects/practice/venv/local/lib/python2.7/site-packages/django/contrib/auth/__init__.py" in login
126. if SESSION_KEY in request.session:
Exception Type: AttributeError at /login/
Exception Value: 'Login' object has no attribute 'session'
There are a few errors here. The main one of attempting to render within the form login_user method. Apart from anything else, you attempt to pass the self as the request parameter to render, which mages no sense.
Remove all of that if/else. You don't need to render; but also note that your if condition is needlessly inefficient. If you get a user, it's necessarily a User.
Finally, the actual cause of your error, where again you are trying to pass self in the place of a request, but this time as the parameter to login. That code belongs in the view.
And finally, the form is not a ModelForm, so there is no save method.
So, form:
def login_user(self):
email = self.cleaned_data['email']
password = self.cleaned_data.get('password')
return authenticate(email=email, password=password)
and view:
if login_form.is_valid():
user = login_form.login_user()
if user:
login(request, user)
return HttpResponseRedirect(reverse('dashboard'))
Although at this point you may as well move all that logic to the view.
login() get as first argument the request, you call it with the form as first argument.
https://docs.djangoproject.com/en/2.1/topics/auth/default/#django.contrib.auth.login

Django registration | change behaviour

After succesfully registering, the user is redirected to the template 'registration_done.html'.
Is there any way of changing this behaviour to redirecting the user to the registration page and displaying a message?
I tried these code below also tried different ways to change it but have different types of errors in different cases.
urls.py
url(r'^register/$',
views.register,
{
'success_url': '/accounts/register/?success=true'
},
name='register'),
view.py
def register(request):
if request.method == 'POST':
user_form = UserRegistrationForm(request.POST)
if user_form.is_valid():
# Create a new user object but avoid saving it yet
new_user = user_form.save(commit=False)
# Set the chosen password
new_user.set_password(user_form.cleaned_data['password'])
# Save the User object
new_user.save()
success = request.GET.get('success', None)
return render(request, {'new_user': new_user, 'success': success})
else:
user_form = UserRegistrationForm()
return render(request, 'account/register.html', {'user_form': user_form})
registration.html:
{% if success %}
<p>{% trans 'Successfull registration!' %}</p>
{% endif %}
Whats wrong I did?!
Error:
Traceback (most recent call last):
File "C:\Python34\lib\site-packages\django\core\handlers\base.py", line 149, in get_response
response = self.process_exception_by_middleware(e, request)
File "C:\Python34\lib\site-packages\django\core\handlers\base.py", line 147, in get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
TypeError: register() got an unexpected keyword argument 'success_url'
[18/Aug/2016 14:17:55] "GET /en/account/register/ HTTP/1.1" 500 59886
You are trying to pass the kwarg success_url to your function register
Your function register(request) only accepts one argument: 'request'.
So you can accept a second argument, say success_url, like so
def register(request, success_url):
...
But there is no point doing that if success_url is a constant. In that case, just define it your register function
def register(request):
success_url = 'foo'
Another point here is that you want to reverse that url, rather than hard code it.
Also I'm not sure why you would want to use this:
success = request.GET.get('success', None)
Any user could submit their own success variable in the GET request. Are you expecting this from a form? Looks like a security vulnerability if the user can just say that the were successful in request.GET.
Right now you aren't actually rendering a template on success anyway because you are missing a template name/path from your first render call.
So either add a template or redirect them to another page.

View didn't return an HttpResponse object. It returned None instead

The view below is gives me the error when using the POST method. I'm trying to load the model data into a form, allow the user to edit, and then update the database. When I try to Save the changes I get the above error.
def edit(request, row_id):
rating = get_object_or_404(Rating, pk=row_id)
context = {'form': rating}
if request.method == "POST":
form = RatingForm(request.POST)
if form.is_valid():
form.save()
return redirect('home.html')
else:
return render(
request,
'ratings/entry_def.html',
context
)
Here is the trace from the terminal.
[15/Apr/2016 22:44:11] "GET / HTTP/1.1" 200 1554
[15/Apr/2016 22:44:12] "GET /rating/edit/1/ HTTP/1.1" 200 919
Internal Server Error: /rating/edit/1/
Traceback (most recent call last):
File "/Users/michelecollender/ENVlag/lib/python2.7/site-packages/django/core/handlers/base.py", line 158, in get_response
% (callback.__module__, view_name))
ValueError: The view ratings.views.edit didn't return an HttpResponse object. It returned None instead.
You are redirecting if form.is_valid() but what about the form is invalid? There isn't any code that get's executed in this case? There's no code for that. When a function doesn't explicitly return a value, a caller that expects a return value is given None. Hence the error.
You could try something like this:
def edit(request, row_id):
rating = get_object_or_404(Rating, pk=row_id)
context = {'form': rating}
if request.method == "POST":
form = RatingForm(request.POST)
if form.is_valid():
form.save()
return redirect('home.html')
else :
return render(request, 'ratings/entry_def.html',
{'form': form})
else:
return render(
request,
'ratings/entry_def.html',
context
)
This will result in the form being displayed again to the user and if you have coded your template correctly it will show which fields are invalid.
I was with this same error, believe it or not, was the indentation of Python.
your error to the indentation of a Python file. You have to be careful when following tutorials and/or copy-pasting code. Incorrect indentation can waste lot of valuable time.
You Should Return What file you are rendering instead of Direct Render.
def index(request):
return render(request, 'index.html')
def login(request):
return render(request,'login.html')
def logout(request):
return render(request,'index.html')

Categories

Resources