I am trying to write a basic website in django. I need the user (i'm still using the default one) to be able to login, logout, register, etc. I have the basic functionality set up, but I want the user to be able to visit a profile page where it will display basic information about the user. Naturally, the profile page must use the login_required decorator but the way I have it set up now is that once anybody signs in they can see any profile page.
Part of the URL file:
url(r'^profile/(?P<username>[\w.#+-]+)/$',
login_required(ProfilePageView.as_view())),
As you can see, the url should consist of "profile/" follow by the username of the user. How can I set it up so that only the user with the username following the "profile/" part of the url can see that page. With this code some user could login with any username and then just change the url and resend the get request.
You can do something like this. if you have created a Profile model for each user you can also access the Profile information using profile_info=request.user.profile
def login_user(request):
username=request.POST.get('username','')
password=request.POST.get('password','')
user=auth.authenticate(username=username,password=password)
if user is not None:
auth.login(request,user)
return HttpResponseRedirect('/loggin/')
else:
return HttpResponseRedirect('/invalid/')
def loggin(request):
username=None
if request.user.is_authenticated:
#profile_info=request.user.profile
info=request.user
return render(request,'base.html',locals())
<head>
<body>
<h5>{{info.first_name}}{{info.first_name}}</h5>
</body>
</head>
Related
I know there are a few questions on the topic already but I have tried to implement those solutions and could not really solve my problem.
I am talking about social signup with allauth here, and facebook in particular.
DESIRED BEHAVIOR: after facebook signup I want user to go to my url "accounts:welcome", but when they simply login I want them to go to my LOGIN_REDIRECT_URL (which is the site's home page).
After looking here and there this is the code I came up with (writing my custom adapter)
settings.py:
LOGIN_REDIRECT_URL = ("gamestream:home")
SOCIALACCOUNT_ADAPTER = "myproject.users.adapter.MySocialAccountAdapter"
adapter.py:
from django.conf import settings
from allauth.socialaccount.adapter import DefaultSocialAccountAdapter
from django.core.urlresolvers import reverse
from django.shortcuts import redirect
class MySocialAccountAdapter(DefaultSocialAccountAdapter):
def save_user(self, request, sociallogin, form=None):
print('OK11OK')
super().save_user(request, sociallogin, form=form)
return redirect(reverse('accounts:welcome'))
def get_connect_redirect_url(self, request, socialaccount):
print('OK22OK')
assert is_authenticated(request.user)
url = reverse('accounts:welcome')
return url
Please assume that all links/settings are good as for example the console prints out 'OK11OK' when I create myself as a user via the facebook app. The fact is that the method get_connect_redirect_url never gets triggered as I never read 'OK22OK' on the console.
The user is created and I end up on the home page, which is not what I want.
So I thought that after the save_user method something else gets called as I can tell that I pass through accounts:welcome, but then end up on the home page.
I can tell this because if I return an incorrect url in the save_user method I get an error that is specific to that url on that line.
So, what is wrong here?
I think I might be overriding the wrong method but I have read all the code of the base SocialAccountAdapter and I can't see anything else that would be the right choice.
Just wanted to mention that as I have more control on the normal account signup (not social) I have achieved what I wanted.
Any ideas?
Thanks very much!
I had the same problem too, I found two methods:
METHOD 1
Django doesn't use redirection function of the DefaultSocialAccountAdapter, you'll have to override the get_signup_redirect_url function of DefaultAccountAdapter to achieve the result.
First you need to change the default adapter in settings.py:
ACCOUNT_ADAPTER = 'users.adapter.MyAccountAdapter'
Then, just override the get_signup_redirect_url with your url:
# project/users/adapter.py
from allauth.account.adapter import DefaultAccountAdapter
class MyAccountAdapter(DefaultAccountAdapter):
def get_signup_redirect_url(self, request):
return resolve_url('/your/url/')
METHOD 2
This is the easier one
If you take a look at the source code at DefaultAccountAdapter it says:
Returns the default URL to redirect to after logging in. Note
that URLs passed explicitly (e.g. by passing along a next
GET parameter) take precedence over the value returned here.
So, you can pass along a next parameter in your login template to force the redirection. Here is an example using Google social login:
{% load socialaccount %}
{% providers_media_js %}
{# your html tags #}
<body>
SOCIAL LOGIN
</body>
Of course you can personalize the next url (I'm refering to /success/url/) as you wish. You can pass a context variable with your desired url and put it there instead of that hardcoded url.
The current flow for visitors with django-allauth is if the visitor fills in a form, if they are not already authenticated they are shown a login modal with option of facebook login or standard signup form, with the original form data being saved in ACCOUNT_SIGNUP_FORM_CLASS=SignupForm
class SignupForm(forms.Form):
def signup(self, request, user):
new_user = Profile()
new_user.user = user
new_user.save()
# if form data provided with signup save it.
model = self.cleaned_data['model']
if model:
# save the form
This works fine if the user signs up using the standard signup form, but if they signup using facebook social account the values from the form are now empty strings i.e. self.cleaned_data['model']. I assume the original request object is destoryed so the post data is lost? There also doesn't seem anyway to pass the form data to facebook and receive it back e.g.
<a title="{{provider.name}}" href="{% provider_login_url provider.id modal="1" process="login" next=request.path scope=scope auth_params=auth_params %}"
Is the only way to do what I want is to save the form data using local storage or the database then somehow assign it back to the visitor once registered and save it?
What I've gone with is changing the Facebook signup button to link to an intermediate view where I save the form data as session data and then redirect back to the allauth facebook login url.
I then extract the form data from the session in the signup method after the user has authenticated with facebook.
I am working on an app where the user will be able to login to his profile. I am using Django-registration-redux. I am using the below code to inculde in my project.
LOGIN_REDIRECT_URL = '/profile/view/(?P<pk>[0-9]+)/'
I want to redirect the user to his profile after logging in. I know that is not the way you can actually call an url in settings file. any solution for the problem?
I believe you can use https://docs.djangoproject.com/en/dev/ref/urlresolvers/#reverse-lazy to add URL resolution to a setting.
You don't need to pass the user pk to the view. You can get this value and every other data field of the user from request.user object.
As stated in Django docs, you could do something like this:
def profile(request):
if request.user.is_authenticated:
# Do something for logged-in users.
request.user.do_something()
[...]
else:
# Do something for anonymous users like redirect to registration
pass
I am new to django and to userena. I have implemented django userena and the login page which is working fine. Currently after successful login the user is redirected to profile page. I want to change this and do two things:
1. Redirect the user to the home page after successful login and not profile page and second
2. The homepage and all other pages should detect the user session and use the session variables for the particular user to customize the page.
Please let me know how should I achieve this.
THanks!
To redirect use:
USERENA_SIGNIN_REDIRECT_URL = 'your_url'
the user should always be available and you could do things like self.request.user.is_authenticated() in a view or {{ user.is_authenticated }} in a template
This is how am I doing it to check if the user is signed in.
#views.py
from userena.views import signup, signin
def sign_up(request):
#if user is authenticated, redirect to user's profile page
#otherwise use userena signup view, with my own form,SignupFormExtra, instead of userena's
if request.user.is_authenticated():
username = request.user.username
return HttpResponseRedirect('/accounts/'+username)
else:
return signup(request,signup_form=SignupFormExtra)
def sign_in(request):
if request.user.is_authenticated():
username = request.user.username
return HttpResponseRedirect('/accounts/'+username)
else:
return signin(request)
and in my urls.py I have
url(r'^accounts/signup/$', 'accounts.views.sign_up'),
url(r'^accounts/signin/$', 'accounts.views.sign_in'),
I'm playing around with django and built a small app where a user can access their info via the url http:///localhost:8000/username/info/ . I want to add the ability to edit that info through http:///localhost:8000/username/info/edit/, but also want to make sure the currently logged in user (using django.contrib.auth) can access only his information. I accomplished this by doing the following in the view (username in the view args is captured from the url):
#login_required
def edit_info(request, username=''):
if request.user.username == username:
# allow accessing and editing the info..
else:
# redirect to some error page
So, obviously, I don't want user 'johnny' to edit the info belonging to user 'jimmy' by simply pointing his browser to /jimmy/info/edit/. The above works, but my concern is that I'm missing something here as far as security goes. Is this the right way to go about this?
Thanks.
This should work for what you are trying to do without any glaring security risks.
But, why show their username if no one else can see at least a profile or something at this location though? Wouldn't this be more like a 'account' page? Then you wouldn't check against the username in the url, the only url you could go to would be account, and it would just load the logged in user's info.
With the #login_required and parsing the request.user they will never end up on anothers profile. My profile view
#login_required
def user_profile(request):
""" User profile page """
u = User.objects.get(pk=request.user.pk)
return render_to_response('myapp/user_profile.html', {
'user': request.user,
})
Then in the template simply use stuff like:
Welcome <b>{{ user.first_name }} {{ user.last_name }}</b>