'function' object has no attribute 'get' in django - python

I am trying to make a user not able to ask a Question only when he is logged in.
This is the error I'm getting in my terminal window:
Internal Server Error: /ask_question/
Traceback (most recent call last):
File "/home/rayan/.local/lib/python3.8/site-packages/django/core/handlers/exception.py", line 34, in inner
response = get_response(request)
File "/home/rayan/.local/lib/python3.8/site-packages/django/utils/deprecation.py", line 96, in __call__
response = self.process_response(request, response)
File "/home/rayan/.local/lib/python3.8/site-packages/django/middleware/clickjacking.py", line 26, in process_response
if response.get('X-Frame-Options') is not None:
AttributeError: 'function' object has no attribute 'get'
[23/Jul/2020 17:19:16] "GET /ask_question/ HTTP/1.1" 500 62327
I am using a decorator, this is the code in my decorators.py:
def usersOnly(view_func):
def func(request, *args, **kwargs):
if request.user.is_authenticated:
return view_func
else:
return redirect('login')
return func
And this is the code in my views.py:
#usersOnly
def ask_question(request):
form = AskQuestion()
if request.method == "POST":
asker = request.user
form = AskQuestion(request.POST)
if form.is_valid():
form.save()
id = form.cleaned_data.get('id')
return redirect(f'/question/{id}/')
dic = {
"form":form,
}
return render(request, 'blogs/ask_question.html', dic)
And this is the code from my models.py:
class Question(models.Model):
title = models.CharField(max_length=250)
asker = models.ForeignKey(User,on_delete=models.CASCADE)
text = models.TextField()
pub_date = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.title
I am trying to allow only the logged in users to ask a question, if the user isn't logged in, he will be redirected to the login page. But it is giving me an error.

You need to call the function in the decorator, and return the result of the function, not the function itself:
def usersOnly(view_func):
def func(request, *args, **kwargs):
if request.user.is_authenticated:
return view_func(request, *args, **kwargs)
else:
return redirect('login')
return func
But what you here aim to do, already exists. You can make use of the #login_required decorator [Django-doc]:
from django.contrib.auth.decorators import login_required
from django.urls import reverse_lazy
#login_required(login_url=reverse_lazy('login'))
def ask_question(request):
# …

Related

AttributeError: 'tuple' object has no attribute 'get' with redirect(reverse) in django

my django app has a form view for submitting information that creates a new post, after which it should redirect to a thank you page.
def submit(request, slug):
account = get_object_or_404(Account, slug=slug)
if request.method == "POST":
# process the data and post form as JSON
ret = create_or_edit_post(request, account, post=None, duplicate=False)
if isinstance(ret, HttpResponseRedirect):
post = account.posts.latest('id')
# handle post info and post creation
return redirect(reverse('post-submit-ty', kwargs={'slug': account.slug}))
return ret
context = { "account": account }
return render(request, 'submit.html', context)
since the redirect(reverse(...)) returns a tuple, this throws:
AttributeError: 'tuple' object has no attribute 'get'
File "django/core/handlers/base.py", line 131, in get_response
response = middleware_method(request, response)
File "newrelic/hooks/framework_django.py", line 325, in wrapper
return wrapped(*args, **kwargs)
File "django/middleware/clickjacking.py", line 32, in process_response
if response.get('X-Frame-Options') is not None:
since I need to pass slug kwarg (as a tuple) and redirect to the thank you page but it's looking for an http response is there a way to handle this with redirect(reverse) or HttpResponseRedirect(reverse)? thanks
Actually you can pass a view name with arguments and redirect is gonna do internally a reverse.
Try this, redirect('post-submit-ty',slug=account.slug).
Django Shourtcuts redirect

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

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

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)

Fom missing 1 required positional argument: 'request' in form

I am trying to get my form work using previous stackoverflow answers and google but nothing seems to work for me.
I have a model Project and a project team and I would like the user to be able to choose from one of the teams that he created and link it to the project.
I am using a custom user called MyUser
that is my form in order to select a team:
from django import forms
from django.contrib.auth.models import User
from registration.models import MyUser
from .models import Project, Team
from django.contrib.auth import get_user_model
User = get_user_model()
class EditSelectTeam(forms.Form):
team_choice = forms.ModelChoiceField(widget=forms.RadioSelect, queryset=None)
def __init__(self, User, request, *args, **kwargs):
super(EditSelectTeam, self).__init__(*args, **kwargs)
self.fields['team_choice'].queryset = Team.objects.all().filter(team_hr_admin = request.User)
my views:
def TeamSelect(request):
if request.method == "POST":
select_form = EditSelectTeam(request.user, request.POST)
if select_form.is_valid():
print('sucess')
else:
print('Fail')
else:
select_form = EditSelectTeam(request)
return render(request,'link_project.html',
{'select_form':select_form })
If in my form I put request.User I get the error in my view that :
TypeError: __init__() missing 1 required positional argument: 'request'
If I do not put user in my __init__ I get the form but when I click POST I get the error
AttributeError: 'MyUser' object has no attribute 'user'
Your __init__ method takes User and request,
def __init__(self, User, request, *args, **kwargs):
but you only ever pass one of these to the form:
select_form = EditSelectTeam(request.user, request.POST)
...
select_form = EditSelectTeam(request)
I would change the __init__ method to just take user (lowercase),
def __init__(self, user, *args, **kwargs):
super(EditSelectTeam, self).__init__(*args, **kwargs)
self.fields['team_choice'].queryset = Team.objects.all().filter(team_hr_admin=user)
then change the view to always pass request.user.
select_form = EditSelectTeam(request.user, request.POST)
...
select_form = EditSelectTeam(request.user)

Django: class-view lacking attribute COOKIES

I am currently playing around with REST and backbone.js and ran into this issue:
'LoginView' object has no attribute 'COOKIES'
Here comes the following code for might have caused the problem. I have commented out a few things in the javascript, since I wanted it to load directly to the server instead, but I thought it would be just as good to bring it along.
I can also add that I have checked for the csrf-token in the form and it is there.
views.py
class LoginView(TemplateView):
authentication_form=LoginForm
form_class = LoginForm
redirect_field_name=REDIRECT_FIELD_NAME
template_name = 'front/login.html'
initial = {'key': 'value'}
def get(self, request, *args, **kwargs):
form = self.form_class(initial=self.initial)
return render(request, self.template_name, {'form': form})
#method_decorator(sensitive_post_parameters())
#csrf_protect
#never_cache
#api_view(['GET', 'POST'])
def post(self, request, *args, **kwargs):
form = self.form_class(request.POST)
print request.COOKIES('csrftoken')
print request.POST.get('csrfmiddlewaretoken')
if form.is_valid():
#if not is_safe_url(url=redirect_to, host=request.get_host()):
# redirect_to = resolve_url(settings.LOGIN_REDIRECT_URL)
print request.POST.get('email')
#user = self.get_user(request.POST.get('email'))
#print user
#auth = UserDataAuthentication(request, user)
user = authenticate(email=request.POST.get('email'), password=request.POST.get('password'))
if user is not None:
auth_login(request, user)
return Response(user, status=status.HTTP_201_CREATED)
return HttpResponseRedirect('/login/')
login.js
var csrftoken = $('meta[name="csrf-token"]').attr('content');
SigninView = Backbone.View.extend({
events: {
//"click button[type=submit]": "sendRequest"
},
sendRequest: function( event ){
//event.preventDefault();
var csrftoken = $.cookie('csrftoken');
var url = '/login/validate/';
var email = $("#id_email").val();
var password = $("#id_password").val();
var items = {
email: email,
password: password,
csrfmiddlewaretoken: csrftoken
};
console.log(csrftoken);
$.ajax({
url:url,
type:'POST',
dataType:"json",
data: items,
success: function (data) {
var json = $.parseJSON(data);
console.log(data);
},
error: function (xhr, textStatus, error) {
$("#form_error").css('padding','7px').css('border-radius','4px').html('Error recieved: ' + error).fadeIn();
console.log("Status: "+textStatus);
console.log("Type: "+error);
}
});
}
});
var signin_view = new SigninView({
el: $("#login_form")
});
We are two people working on this, I have taken upon myself to work with Python, while my friend takes care of the js-part. I have yet to experience enough of Django to actually find what might have caused an error to arise due to cookies. I try, most of the time, to stay away from cookies, if I can, but it seems difficult here.
And of course: The traceback:
Traceback:
File "/home/ryuu/Programming/Python/tabr/venv/local/lib/python2.7/site-packages/django/core/handlers/base.py" in get_response
114. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/home/ryuu/Programming/Python/tabr/venv/local/lib/python2.7/site-packages/django/views/generic/base.py" in view
69. return self.dispatch(request, *args, **kwargs)
File "/home/ryuu/Programming/Python/tabr/venv/local/lib/python2.7/site-packages/django/views/generic/base.py" in dispatch
87. return handler(request, *args, **kwargs)
File "/home/ryuu/Programming/Python/tabr/venv/local/lib/python2.7/site-packages/django/utils/decorators.py" in _wrapper
29. return bound_func(*args, **kwargs)
File "/home/ryuu/Programming/Python/tabr/venv/local/lib/python2.7/site-packages/django/views/decorators/debug.py" in sensitive_post_parameters_wrapper
75. return view(request, *args, **kwargs)
File "/home/ryuu/Programming/Python/tabr/venv/local/lib/python2.7/site-packages/django/utils/decorators.py" in bound_func
25. return func(self, *args2, **kwargs2)
File "/home/ryuu/Programming/Python/tabr/venv/local/lib/python2.7/site-packages/django/utils/decorators.py" in _wrapped_view
95. result = middleware.process_view(request, view_func, args, kwargs)
File "/home/ryuu/Programming/Python/tabr/venv/local/lib/python2.7/site-packages/django/middleware/csrf.py" in process_view
111. request.COOKIES[settings.CSRF_COOKIE_NAME])
Exception Type: AttributeError at /login/validate/
Exception Value: 'LoginView' object has no attribute 'COOKIES'
You used functions decorators on a method.
This won't work: the function as returned by the decorator expects its first argument to be a request, and receives self instead.
Use:
from django.utils.decorators import method_decorator
csrf_protected_method = method_decorator(csrf_protect)
# and so on
Check the documentation for more details.

Categories

Resources