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.
Related
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):
# …
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
I use the Django framework as backend and vue.js and webpack for the frontend. to implement authentication, send a request via ajax to Django and want to keep session for next requests but can not keep session.
I use the request node module for send request and use the jar to keep session but get error 403 again. it means jar does not keep the session for this user.
in vuejs:
var request = require('request');
get_jar(){
if(this.jar){
return this.jar;
}
this.jar = request.jar();
return this.jar;
}
send_ajax(url, data, method, callback){
request(
{
url: url,
method: method,
form: data,
jar: this.get_jar(),
},
function(err, res, body){
callback(err, res, body)
});
}
in django:
#method_decorator(csrf_exempt, 'dispatch')
class Login(View):
#staticmethod
def post(request):
email = request.POST.get('email', None)
password = request.POST.get('password', None)
user = authenticate(request, username=email, password=password)
if user is None:
return JsonResponse({'message': 'incorrect username or password'}, status=403)
else:
login(request, user)
return JsonResponse({'message': 'user logged in'})
a decorator for check user log in:
def user_login_required(method):
#wraps(method)
def wrap(request, *args, **kwargs):
if request.user.is_authenticated:
return method(request, *args, **kwargs)
else:
return JsonResponse({'message': 'user not recognized'}, status=403)
return wrap
can somebody help me, please?
I am building an API which accepts file and validates it, sends json response (not storing the file in db, so no need of model). I have created a class based view, in post function, request.FILES or request.POST doesn’t contain the file… If I make a form class, it will work. But, I don’t want any UI, it should be a simple API. Anyone knows how to do it?
class ValidateView(View):
def get(self, request, *args, **kwargs):
pass
def post(self, request, *args, **kwargs):
file = request.FILES
if not file:
return JsonResponse({"status_code": "400", "message": "a file is required", "status_response": "Bad Request"})
return JsonResponse({"status_code": "200", "message": "data validated", "status_response": "Success"})
#csrf_exempt
def dispatch(self, request, *args, **kwargs):
return super(ValidateView, self).dispatch(request, *args, **kwargs)
I used djangorestframework and come up with this
class ValidateView(views.APIView):
parser_classes = (FileUploadParser,)
def post(self, request, filename, format=None):
file_obj = request.data['file']
if is_csv_valid(file_obj):
return Response(status=200, data={"message": "valid file"})
else:
return Response(status=400, data={"message": "not valid"})
But, here the problem is I must build a url like this
re_path("validate/(?P<filename>[^/]+)$", ValidateView.as_view(), name="api-validate")
If I exclude filename in url, it throws an error. Also, file_obj contains some extra lines along with original data like this.
[b'----------------------------634867545113999762020341\r\n', b'Content-Disposition: form-data; name=""; filename="kafka_word_count_input.txt"\r\n', b'Content-Type: text/plain\r\n', 'original_data']
Someone help!!!
you can create the serializer
class FileSerializer(serializer.Serializers):
file = serializer.FileFiled()
def validate_file(self, value):
# write logic to validate
if not is_csv_valid(value):
raise serializer.ValidationError("wrong file")
else:
return value
class ValidateView(views.APIView):
serializer_class = FileSerializer
def post(self, request, filename, format=None):
serializer = self.serializer_class(data=request.data)
if serializer.is_valid(raise_exception=True):
return Response(status=200, data={"message": "valid file"})
now send the reuqest in form data
Figured it out... The problem is I am not sending key file from postman. This I figured it out, when using curl... wowww, command line tools rocks...
also, I need to use request.FILES['file'] to access file and do my stuff...
I am using Django-registration-email in my Django project. In there documentation (Django-Registration-Email), I am instructed to add REGISTRATION_EMAIL_REGISTER_SUCCESS_URL in the settings.py. However, this is causing the type error:
'str' object is not callable
In the settings.py, I set the redirect url as such:
REGISTRATION_EMAIL_REGISTER_SUCCESS_URL = '/accounts/register/complete/'
And the the url is copied as such:
url(
r'^accounts/register/$',
RegistrationView.as_view(
template_name='registration/registration_form.html',
form_class=CustomEmailRegistrationForm,
get_success_url=getattr(
settings,'REGISTRATION_EMAIL_REGISTER_SUCCESS_URL',
lambda request, user:'/'),
),
name='registration_register',
),
And the debug information told me that the first error comes from /local/lib/python2.7/site-packages/registration/views.py in form_valid
The indicated error line is
success_url = self.get_success_url(request, new_user)
The whole block is
def form_valid(self, request, form):
new_user = self.register(request, **form.cleaned_data)
success_url = self.get_success_url(request, new_user)
# success_url may be a simple string, or a tuple providing the
# full argument set for redirect(). Attempting to unpack it
# tells us which one it is.
try:
to, args, kwargs = success_url
return redirect(to, *args, **kwargs)
except ValueError:
return redirect(success_url)
The traceback is:
Traceback:
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/core/handlers/base.py" in get_response
114. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/views/generic/base.py" in view
69. return self.dispatch(request, *args, **kwargs)
File "/Library/Python/2.7/site-packages/registration/views.py" in dispatch
79. return super(RegistrationView, self).dispatch(request, *args, **kwargs)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/views/generic/base.py" in dispatch
87. return handler(request, *args, **kwargs)
File "/Library/Python/2.7/site-packages/registration/views.py" in post
35. return self.form_valid(request, form)
File "/Library/Python/2.7/site-packages/registration/views.py" in form_valid
83. success_url = self.get_success_url(request, new_user)
Exception Type: TypeError at /accounts/register/
Exception Value: 'str' object is not callable
Can anyone help me to solve this issue? Thanks a lot! I am stuck by this problem for one whole day!
OK, when you use
get_success_url=getattr(
settings,'REGISTRATION_EMAIL_REGISTER_SUCCESS_URL',
lambda request, user:'/'),
)
in your url handler, you are setting get_success_url as a string. You are then calling it in form_valid, as a function, trying to pass it variables.
Finally, I find where is the problem: REGISTRATION_EMAIL_REGISTER_SUCCESS_URL is expecting a function rather than a string
So, I should add an one-line function in the settings.py
REGISTRATION_EMAIL_REGISTER_SUCCESS_URL = lambda request, user: '/activate/complete/'
Anyway, I still would like to move to allauth since django-registration-email is no longer maintained.