django redirect does not work - django

I wanted to have function that every time get the request and check that user is login and then return user object if user is login otherwise redirect to login , so this is what I tried to do
def is_login(request):
userID = request.session.get('mainSession', 0)
next = resolve(request.path_info).url_name
print(1)
if userID != 0:
print(2)
user = msignup.objects.filter(id=userID).first()
return user
print(3)
return HttpResponseRedirect(reverse('login') + "?next=
{}".format(next))
I tried to test this function with below view when user is loged out and request has no mainSession :
def email_activation(request):
user = is_login(request)
print(4)
email = user.email
return render(request, 'account/emailActivation.html',{'email':
email})
and in response I got this :
'HttpResponseRedirect' object has no attribute 'email'
and the response for prints that I had made is :
1
3
4
why after 3 redirect does not happens ?what am I doing wrong?

First of all. Django has a few ways to do this built-in. I strongly recomend you to use something that's already made. The login_required decorator would work great for your use case.
https://docs.djangoproject.com/en/1.11/topics/auth/default/#django.contrib.auth.decorators.login_required
Now, if what you're doing is an experiment. The problem that you have is that you are returning the response Redirect object on is_login. What you could to do to make this work (i again recommend you to not go with this route), is make another function that redirects to the login page, and have the is_login function just return True or False if the user is login or not.
Then you will be able to do something like:
if not is_login(request):
return redirectToSigninPage(request)

Related

how to create a custom session for log in user in Django

I am trying to login a user by sending a post request to an endpoint, the endpoint is returning status of 200 means the user information is true, but what i have been doing previously in django is simplify using authenticate method and passing user_phone and password later setting that resul to login(request, user_phone), now I dont know what to do here as here I am getting a response from that api which is just a user id, can we do something custom for this result.
user_is_authenticated = res['data']['user_id']
print('response',res['data']['user_id'] )
request.session['user_is_authenticated'] = True
print('response',request.session['user_is_authenticated'])
return render(request, "app/com-dashboard.html",{'user_is_authenticated':user_is_authenticated } )
here i am getting user_id, i just want to use user_is_authenticated just like we do in normal django app

Alternative of Requests in django

In my project I'm trying to hit a url(which is running in same project) in my view.
so in simplest way I can explain here.
#login_required
def my_api_view(request):
if requests.method == 'GET':
# do stuff
return JsonResponse()
# and its url is `/api/get-info/`
another view which is consuming above api
#login_required
def show_info(request):
url = get_base_url + /api/get-info/ # http://localhost:8000/api/get-info/
r = requests.get(url)
return HttpResponse(r.json())
Now I have to use same session (login required) so when I hit the url using requests it complains that user is not loggedin which is obviously correct.
How can I do this elegantly and efficienty. session use of logged in user. (I dont want to call the view as a function, I want to hit the api-url end point and consume.
PS: we have something similar in django Test self.client.get(...)
Just call that view function and pass the request object as parameter to it.
#login_required
def show_info(request):
r = my_api_view(request)
return HttpResponse(r.json())
Or a better option would be to simply separate the logic into a separate function, as mentioned by #koniiiik in the comments.
EDIT: Or if you really want to hit the URL endpoint, you can simply pass on the cookie values to the request you make.
#login_required
def show_info(request):
url = get_base_url + "/api/get-info/" # http://localhost:8000/api/get-info/
r = requests.get(url, cookies=request.COOKIES)
return HttpResponse(r.json())

no user matches the given query while using username as an argument

Till now i have been using userid's (pk) as an argument in the profile urls for my application. Recently i decided to use the username instead of the user id's So i changed the following :
Urls.py
# This was what i was using previously
url(r'^profile/(?P<uid>\d+)/$', 'app.views.user_profile', name="profile"),
# Changed the above to this.
url(r'^profile/(?P<username>[-\w\d]+)/$', 'app.views.user_profile', name="profile"),
Views.py
# Previous view
#login_required
def user_profile(request, uid):
user = get_object_or_404(models.User, pk=uid)
profile = helpers.get_profile(user)
render_to_response('profile.html', {'profile' : profile})
# Changed the above to
#login_required
def user_profile(request, username):
user = get_object_or_404(models.User, username=username)
profile = helpers.get_profile(user)
render_to_response('profile.html', {'profile' : profile})
Until Now it's all good. When i try to visit 127.0.0.1:8000/profile/some_username/ instead of the previous 127.0.0.1:8000/profile/some_number/ it works fine.
I have a toolbar in the profile.html, which contains links such as:
/profile/edit/
/profile/settings/
in the urls.py these urls map to very simple views. Such as the following.
#login_required
def profile_settings(request):
"""
This view helpers.renders the profile's settings panel
"""
print 'hello'
rec, can = helpers.get_user_or_noprofile(request.user)
if not can is None:
gform = forms.CandidateGeneralSettingsForm(instance=can)
jsform = forms.CandidateJobSearchSettingsForm(instance=can)
data = {'candidate' : can, 'gform' : gform, 'jsform' : jsform }
else:
form = forms.RecruiterSettingsForm(instance=rec)
data = { 'recruiter' : rec, 'form' : form }
return helpers.render(request, 'profile_settings.html', data)
The weird part is after i changed to use username in the profile url. As soon as i click on any of the links in the toolbar, i see the 404 : Error : No User matches the given query. page.
To debug i tried printing a few debug statements within these views and found out something more weird. Nothing gets printed even if i Comment the whole code inside the view and just write a print statement.
This makes me doubt that the problem might be with the login_required decorator. but if that's the case howcome it is working while visitng 127.0.0.1:8000/profile/some_username/.
I really can't think of anything that might be causing this. Any help will be greatly appreciated. Thanks.
PS: Also, JFYI, i am using a custom Email Authentication backend that lets user login through their email address instead of the username.
It doesn't work because edit is not a valid username.
This url /profile/edit/ matches ^profile/(?P<username>[-\w\d]+)/$, and username becomes edit.
Since you don't have a user called "edit", this user = get_object_or_404(models.User, username=username) fails, and raises a 404.
The same for /profile/settings/.

Django user authentication error

I am using the following code to login, but later when I navigate from index.html and try to access the get_profile() it says the id is not associated. But when I print the following variables both are false. What am I doing wrong here?
EDIT
def someotherview(request):
logging.debug(request.user.is_authenticated()) #prints false
logging.debug(request.user.is_active) #prints false
This is how the login
def logon(request):
qd = get_request_type(request)
try:
uname = qd.__getitem__('username')
pwd = qd.__getitem__('password')
user = authenticate(username = uname, password = pwd)
if user is not None:
response_dict.update({'yes':1})
logging.debug("labs_home1 ==================")
return render_to_response('home/index.html', context_instance=RequestContext(request, {'response_dict':response_dict,'a':1}))
else:
response_dict.update({'yes':0})
logging.debug("labs_home2 ==================")
return render_to_response('registration/login.html', context_instance=RequestContext(request, {'response_dict':response_dict,'a':1})
Also have a look at my question django get_profile error
authenticate only verifies that username and password are correct and returns User instance found for that pair. To actually log user in and have it available in templates, sessions etc you need to call login
login(request, user)
short answer: use the built-in authentication. Don't try to write youu own. https://docs.djangoproject.com/en/dev/topics/auth/
your code is totally broken - in the login view the variables uname and pwd are undefined. please post working code.
you seem to be doing authentication yourself - why don't you just use the built in authentication methods?
it looks like part of your problem is that you defining a logged-in user with the variable user but that only exists in the scope of the function logon - the rest of your code is checking request.user. This is why you need to use the built in authentication methods.

Django-registration setup without password

I am trying to make a website, where people only put their email addresses and they are logged in with cookies and all. At a later stage, i will ask them provide password and names, but NO username will be used. I am trying to do this with django-registraition, but i get errors and i have a few problems.
First to disable usernames as a login feature, i put str(time()) instead of username - i was looking for something that will change every time.
However, when I skip the authentication (which i currently don't need) i get error:
'RegistrationProfile' object has no attribute 'backend'
Alternatively, i can leave the authentication but then i don't know how to authenticate it only with email and no password. Also, i don't know how to make the next line work:
auth.login(request, ProfileUser)
If anyone can get me out of here, it would be awesome. Here is some code:
my form Class:
class RegistrationFormCustom(forms.Form):
email = forms.EmailField()
def do_save(self):
new_u = User(username=str(time()),email= self.cleaned_data.get('email'),)
new_u.save()
new_p = Profile.objects.create_profile(new_u)
new_p.save()
return new_p
my view:
def registerCustom(request, backend, success_url=None, form_class=None,
disallowed_url='registration_disallowed',
template_name='registration/registration_form.html',
extra_context=None,
initial={}):
form = RegistrationFormCustom(initial=initial)
if request.method == 'POST':
form = RegistrationFormCustom(initial=initial, data=request.POST)
if form.is_valid():
profile = form.do_save()
profile = auth.authenticate(username = profile.user.email, password = form.cleaned_data.get('pass1'))
print(profile)
auth.login(request, profile)
return redirect('/')
else:
pass
return render_jinja(request, 'registration/registration_form.html',
type="register",
form = form
)
and i will post any other snipped required happily
You're getting the 'RegistrationProfile' object has no attribute 'backend' error because the user is not yet authenticated. To log someone in, you have to call the authenticate method first, which requires a password. So, what you can do instead, is this:
from django.contrib.auth import load_backend, login, logout
from django.conf import settings
def _login_user(request, user):
"""
Log in a user without requiring credentials (using ``login`` from
``django.contrib.auth``, first finding a matching backend).
"""
if not hasattr(user, 'backend'):
for backend in settings.AUTHENTICATION_BACKENDS:
if user == load_backend(backend).get_user(user.pk):
user.backend = backend
break
if hasattr(user, 'backend'):
return login(request, user)
Then, to log someone in, just call the _login_user function with the request and User model. (This will be profile.user in your case, probably) Do this instead of calling auth.login. I'm not sure on how you're going to determine whether this is a valid user or not, without a password or username, but I'll leave that to you. If you still have trouble, let me know.
Short Explanation:
What basically happens here is that Django requires a user to be authenticated in order to be logged in via the login function. That authentication is usually done by the authenticate function, which requires a username and password, and checks whether the supplied password matches the hashed version in the database. If it does, it adds an authentication backend to the User model.
So, since you don't have a password and username, you just have to write your own method for adding the authentication backend to the User model. And that's what my _login_user) function does - if the user is already authenticated, it just calls login, otherwise, it first adds the default backend to the User model, without checking for a correct username and password (like authenticate does).
For others reading this thread, I got a similar error message when I was using User.objects.create() instead of User.objects.create_user(). Basically, the first method was setting a clear password whereas create_user encrypts the password. Clear passwords will fail to authenticate. Check your database, if you have passwords set in the clear, then it's likely you need to use create_user() instead.
The author's request could be fixed by simply setting a default user and password using create_user() instead of just user.save().
You can create a known password (put it in settings.py ) and use that as though the user entered it. Create the user with this and authenticate the user with this.