Hey there I try to use userena with django to build a website which has a clean dashboard after login in. My current problem is that userena uses a pretty high url depth.
Userena is under myproject/accounts and uses the url 'user'. Later 'dashboard'.
When logged in 127.0.0.1:8000/user/ is the userena url. In the normal state it lists all registred users. I've managed to change that to show the current logged in users profile with (accounts/urls.py):
url(r'^$', views.dashboard, name='dashboard'),
url(r'^', include('userena.urls')),
My problem is now that I want to change the normal userena urls.
Userena urls are:
127.0.0.1:8000/user/username/signout
127.0.0.1:8000/user/username/edit
127.0.0.1:8000/user/username/email
127.0.0.1:8000/user/username/password
....
I want:
127.0.0.1:8000/user/signout
127.0.0.1:8000/user/edit
....
I've tried to change both the url and the view but I get always the GuardianError.
Url change:
url(r'^edit', userena_views.profile_edit),
View change:
url(r'^edit', views.settings, name='settings'),
+
def settings(request):
user = request.user
response = userena_views.profile_edit(request, user)
return response
The error:
There are probably multiple ways to archive this. Thank you for the help and sorry for the poor english.
I found a method to solve this here http://tundebabzy.blogspot.de/2013/04/an-easy-way-to-override-third-party-app.html
I practically changed the view like in the tutorial to serve the same files like the original userena view. The case that there will be no username had me to add that extra in the view.
def profile_edit(request, edit_profile_form=userena_forms.EditProfileForm,
template_name='userena/profile_form.html', success_url=None,
extra_context=None, **kwargs):
username = request.user
return userena_views.profile_edit(request=request, username=username,
edit_profile_form=edit_profile_form, template_name=template_name,
success_url=success_url, extra_context=extra_context)
Url:
url(r'^edit/$', views.profile_edit, name='userena_profile_edit'),
Related
I'm trying to use this library to add two factor authentication to my project. I noticed that the module's has its own login view, that you can find right here, see class LoginView(IdempotentSessionWizardView):.
The problem i'm having with this it's that i already have my own login view to handle an authentication form, so why would i use the module's view? I would just need to add the 2FA part to my own view, instead of using another one, but unfortunately that module is not really clear on this part.
So the problem is: how do i integrate their login view into my own login view? How can i just add the 2fa part to my own one without using another login handler?
Any advice is welcome, here is my already existing login view:
def login_request(request):
if request.method == "POST":
if result['success']:
form = AuthenticationForm(request, data=request.POST)
if form.is_valid():
username = form.cleaned_data.get('username')
password = form.cleaned_data.get('password')
user = authenticate(username=username, password=password)
if user is not None:
login(request, user)
messages.info(request, f"You are now logged in as {username}")
return redirect("main:homepage")
else:
messages.error(request, "Invalid username or password")
else:
messages.error(request, "Invalid username or password")
Edit: I've been suggested to use their own login view. Yes, it would be easier. But in the future i would like to add more stuff to the login, such as a captcha form or other fields. But that wouldn't be possible, since i would not be using my own view but the module's view. Is that right?
Converting the discussion from the comments here:
In general, you want to use the batteries-provided views provided by Django before rolling your own, and even before rolling your own from the beginning, you'd want to inherit from and extend the Django views such as LoginView.
The same principle applies to (well-architected) external libraries like the linked django-two-factor-auth.
At first, you'd just use the views included within, probably by directly include()ing the urls module.
Then, if you do need to customize something in those views, you'd inherit from that view, e.g.
from two_factor.views import LoginView
class MyLoginView(LoginView):
template_name = 'super_fancy_login_template.html'
form_list = (
('auth', MyAwesomeAuthenticationForm),
# ... the rest from the original here ...
)
and hook it up in your urls before the library-provided view on the same path:
from django.conf.urls import url
from my_awesome_app.views import MyLoginView
urlpatterns = [
url(
regex=r'^account/login/$',
view=MyLoginView.as_view(),
name='login',
),
include(...),
]
and hey presto, you've replaced a view with your own.
Obviously, the more you replace pieces like this, the less you have any "warranty" (not that open-source software comes with a warranty at all ;) ) that things still work as they should.
After I login, I need to redirect to another page while adding URL parameters to the URL of the next page. I get the value of these parameters after the user is authenticated because they need to be accessed from the user database table. I heard about using the next parameter but I don't know how I would use it since I need to access the database table and I can't do that from urls.py. This is my url.py line for login right now:
url(r'^$',auth_views.login, name='login',kwargs={
'authentication_form':loginPlaceHolderForm,
}),
I'm not really sure what other info you need so just ask for it in the comments and I'll be sure to add it.
Also I'm using Django 1.11
EDIT:
For more clarification: What I want is something like this /colors?team=blue
And let's say the team can be red, blue or green and you get this value from the team column in the given row that you get when the user logs in.
You could try to override djangos class-based view LoginView.
In views.py
from django.contrib.auth.views import LoginView
class MyLoginView(LoginView):
authentication_form = loginPlaceHolderForm
def get_redirect_url(self):
print(self.request.user)
# get data for user here
user_data_query_string = ''
url = '{}?{}'.format(
reverse('app:some-name')
user_data_query_string)
return url
In urls.py
url(r'^$', MyLoginView.as_view(), name='login'),
See also this question about adding GET querystring parameters to djangos HttpRedirect.
I have been using the default django auth for login and I am also using the decorator #login_required for some of the pages. There is no need to remember the previous page if the user hits logout and stuff. The idea is, the user will be redirected to a static page once logged in. How do I do that in django? I do not want to edit login template.
LOGIN_URL = '/accounts/login/' #redirects the user to the login page if not logged in already
LOGIN_REDIRECT_URL = '/something-else' #does not work.
In my urlconf, it's defined like
url(r'^something-else/$', views.something_else, name='something-else')
Any help would be highly appreciated. Thanks.
I'm working on a Django project in which I plan to make user profiles. My goal is to have a standard login page as seen here. After logging in, however, I want to redefine
url(r'^$', 'MyApp.views.home', name='home'),
to not show this page, but a user profile with the same url as home.
For example, www.example.com shows a login screen. After logging it, you're redirected to www.example.com, but you see your profile now.
How can I do this in Django?
You need simple check in view:
if request.user.is_authenticated():
return HttpResponseRedirect('/profileurl/')
An easy way to do it would be a redirect to another view:
MyApp.views
def home(request):
if request.user.is_authenticated():
redirect
else:
home page
If you want the actual url entry to load a different template than the home page, or a modified home page, you could just as easily render whatever template you wanted in response to the url request instead of issuing a redirect
This is generally how I would go about it. You can add context if needed.
views.py:
from django.shortcuts import render
def home(request):
if request.user.is_authenticated():
return user_home(request)
else:
return login_home(request)
def user_home(request)
return render(request, 'path/to/user_template.html')
def login_home(request)
return render(request, 'path/to/login_template.html')
Please visit this link for getting whole idea behind this question
How to Call loggedin username in Django url
Here i have discussed my points in this link but i didnt got specific answer for my issue that , when user loggedin i wanted it to be displayed in my url as
" 127.0.0.1:8000/username " as i got the solution in above link as create user defind HomeRedirectView which calls initially when user logsin. and it works successfully, but i got an issue when i logged out and revisit the url as " 127.0.0.1:8000/ " then this url automatically becomes " 127.0.0.1:8000/AnonymousUser " and am getting the error as "NoReverseMatch", for that i have to specifically write it into url as " 127.0.0.1:8000/home/ " then it works. So can any one suggest me how to make url as " 127.0.0.1:8000/home/ ". To know about what i have done uptill now ,please visit above link and you will come to know from the discussion.
Please suggest.
The solution you got there is not the right solution, the right solution is to use the LOGIN_REDIRECT_URL setting and point it to a view function, a named URL pattern or a direct URL.
Once a user is logged in using the default authentication mechanism of django, the request will automatically be redirected to this page.
Your second problem is when you logout a user, you want to be redirected to a specific URL. If you use the correct solution above, then all you need to do is:
Set LOGOUT_URL in your settings.py.
Create your logout view, it can be as simple as this example from the documentation:
from django.shortcuts import redirect
from django.contrib.auth import logout
def logout_view(request):
logout(request)
return redirect('/home/')
If you want to stick with your original solution, then modify it like this:
class HomeRedirectView(RedirectView):
pattern_name = 'home'
def get_redirect_url(self, *args, **kwargs):
if self.request.user.is_authenticated():
return "/user/{}/".format(self.request.user)
else:
return '/home/'
I think you are overcomplicating things a little, the following will allow you to redirect to a user home page if a user is logged in, or it will display an un-logged in view. I have made the assumption that the username in the URL is purely for display purposes (otherwise it could be a security issue for your application.
urls.py
urlpatterns = patterns('myapp.views',
url(r'^/$', 'home', name='home'),
url(r'^user/[-_.\w\d]+/$', 'user_home', name='user-home'),
)
views.py
from django.contrib.auth.models import User
from django.shortcuts import redirect, render, get_object_or_404
def home(request):
"""
Home page
"""
# If a user is authenticated then redirect them to the user page
if request.user.is_authenticated:
return redirect('user-home', request.user.username)
else:
return render(request, "myapp/home.html")
#login_required
def user_home(request):
"""
User specific home page, assume the username in URL is just for decoration.
"""
return render(request, "mpapp/home_user.html", {
"user": request.user
}