I'm using django-registration app to perform registration. After registration (no matter if successful or not), I'd like to return to whatever page the registation app would redirect, but I want to pass a login form to that template.
Something like this:
def register(request):
registered = reg_views.register(request, backend='registration.backends.default.DefaultBackend', template_name='zzz/index.html')
login_form = AuthenticationForm()
return render_to_response(registered, { 'login_form': login_form })
and then in the template have the ussual:
{{ login_form.as_p }}
Here's what I am trying to achieve:
I want to leverage the functionality of the registration app. However, after a (un)successful registration, I need to be able to display the login form on the page. This login form should be passed from the view (DRY principle).
Thanks,
Matyas
urls.py
urlpatterns = patterns('',
(r'^accounts/', include('external.registration.urls')),
)
new urls.py
urlpatterns = patterns('',
(r'^accounts/register', 'point.to.new.view'),
(r'^accounts/', include('external.registration.urls')),
)
With this set, you can copy the register view somewhere on your code from the registration app, and modify it as you please, without having to modify the app it self. The register view is pretty straight forward so you will have no problem making some changes.
You should not be needed to copy any code from register view of django-registration.
Say, you want to handle authentication functionality in your app named accounts
This goes in accounts/views.py
def registration_complete(request):
login_form = AuthenticationForm()
return render_to_response("registration_complete.html", {"login_form": login_form})
accounts/urls.py
url(r'^registration_complete/', 'accounts.views.registration_complete', name='accounts_registration_complete'),
In your template registration_complete.html
{{login_form.as_p}}
Now you are done with registration_complete setup.
register view of django-registration takes a success_url where it redirects after successful registration.
Provide this success_url as the url we created in accounts.
Your urls.py:
urlpatterns = patterns('',
(r'^registration/register/$', 'registration.register', {'backend': 'registration.backends.default.DefaultBackend', 'success_url': 'accounts_registration_complete'}),
(r'^registration/', include('registration.urls')),
)
Now after registration the user will be redirected to a page which contains the login form.
Related
Django 1.11.3
The documentation about LOGIN_REDIRECT_URL says that:
The URL where requests are redirected after login when the
contrib.auth.login view gets no next parameter.
I have LOGIN_REDIRECT_URL="some_url" in setting.py
I see "next=" (no value, just the key) in the request url when I login, so I suspect that makes Django to ignore LOGIN_REDIRECT_URL and I end up on Admin default page.
I use default login Django functionality, no custom template or anything. How do I get rid of "next=" in my request when I login (completely, no key) to see if LOGIN_REDIRECT_URL will be actually used (hopefully) ?
That’s expected behavior. Normally you want the user requesting any view requiring login (with the #login_required decorator) to be redirected to that same view after login. This is documented here
Since your view url is empty (the home url) you get next=. It’s quite uncommon to have a login required on the home page, from a user perspective it means you can’t see what you're signing up for.
If you remove the #login_required decorator for your view and just add a login button on your homepage (that goes to the regular LoginView) it will not have the next parameter and your users will be redirected to LOGIN_REDIRECT_URL as expected.
Now, if really want users to have to login on your homepage and be redirected to LOGIN_REDIRECT_URL, you have two options:
Remove the #login_required decorator and do the check and redirect in your view:
from django.conf import settings
def homepage(request):
if not request.user.is_authenticated:
return redirect(settings.LOGIN_URL)
# rest of view code
If you're using class-based views, use the LoginRequiredMixin in your view and handle handle_no_permission() yourself:
from django.contrib.auth.views import redirect_to_login
from django.contrib.auth.mixins import LoginRequiredMixin
class Home(LoginRequiredMixin, View):
def get(self):
# your view code
def handle_no_permission(self):
# pass None to redirect_field_name in order to remove the next param
return redirect_to_login(self.request.get_full_path(), self.get_login_url(), None)
If you are having LOGIN_REDIRECT_URL in your settings.py, then in case you are not giving any next parameter to url, it will go to default url mentioned in LOGIN_REDIRECT_URL.
if LOGIN_REDIRECT_URL = 'some/path/'
https://yourdomain.com/login/ will redirect to 'some/path/'
https://yourdomain.com/login/?next=/override/default/path
will redirect to 'override/default/path'
I am a newbie in django and I was experting different options in Django. I have created a class based view which requires user authentication to view the web page. I am using the inbuilt LoginView.
When the url pattern is specified as follows
url(r'^login/', auth_views.LoginView.as_view(),name='login'),
it is correctly redirected to login page.
But when I give
url(r'^restaurant/login/', auth_views.LoginView.as_view(),name='login'),
I get a 404 when trying to access the page that requires user authentication.
But when I manually go to that url in browser, it works perfectly fine.
Why is that? Shouldn't it both cases work?
It sounds like you need to set LOGIN_URL in your settings:
LOGIN_URL = '/restaurant/login/'
or, it's better to use the URL pattern name, then you don't have to update your settings when you change the login URL
LOGIN_URL = 'login'
Not sure if I'd fully understand your question, just try to give a stupid answer.
Django 2.1.7
use namespace&url name in settings, if you have your own login view just change admin to your url namespace and name your view as 'login'
# settings.py
LOGIN_URL = 'admin:login'
then the login_required decorator will direct you the correct login page.
from django.contrib.auth.decorators import login_required
#login_required()
def month_archive(request, year, month):
production_list = Production.objects.month_archive(year, month)
context = {'production_list': production_list}
return TemplateResponse(request, 'production/production_list.html', context)
If it's a Class Based View, add decorator to urls.py
from django.contrib.auth.decorators import login_required
urlpatterns = [
path('', login_required(views.ProductionList.as_view()), name='production-list'),
path('<int:year>/<int:month>/', views.month_archive, name='production-month'),
]
I have a question, how can I add more than one LOGIN_REDIRECT_URL in settings or in views for my differents users.
For example, I have: Administrators, Human Resources, Teachers, students... etc
and for each I need redirect to a different url, panel admin for Admin etc.
I need add groups? or not?
Thanks for your help!
django-allauth get the login redirect URL from method get_login_redirect_url defined in account adapter you can define your custom adapter and override this:
my_app/adapter.py
from allauth.account.adapter import DefaultAccountAdapter
class AccountAdapter(DefaultAccountAdapter):
def get_login_redirect_url(self, request):
url = super(AccountAdapter, self).get_login_redirect_url(request)
user = request.user
'''
# pseudocode, change it to actual logic
# check user role and return a different URL
role = get_user_role(user)
if role == 'student':
url = student_login_redirect_url
if role == 'teacher':
url = teacher_login_redirect_url
'''
return url
Now tell allauth to use our custom adapter by defining the ACCOUNT_ADAPTER in settings.py:
ACCOUNT_ADAPTER = 'my_app.adapter.AccountAdapter'
I have this URL which takes user to the login page:
url(r'^login_backend', 'fileupload.backend.login_backend'),
Since the user doesn't want to remember:
http://127.0.0.1:8000/login_backend
I want to redirect http://127.0.0.1:8000 to http://127.0.0.1:8000/login_backend without affecting any other activity. I have this decorator above every view:
#login_required(login_url='/login_backend/')
You can use django generic redirect_to view. Add following in your urls.py
urlpatterns = patterns('django.views.generic.simple',
('^$', 'redirect_to', {'url': 'login_backend/'}),
)
I have the following urls
url(r'^signup/','social.views.signup'),
url(r'^submit_signup/','social.views.submit_signup'),
url(r'^signup_complete/','social.views.signup_complete'),
Could I make a url that would choose the view based on the url? Like:
url(r'*/', 'social.views.*')
so that a request to /signup would route to 'social.views.signup'
somehow like this
def test(*args,**kwargs):
view_name = kwargs.pop('view')
view = getattr(social.views,view_name)
return view(*args, **kwargs)
urlpatterns = patterns('',
url(r'^test/(?P<view>.*)$', test),
...
)
or like this
VIEWS_LIST = ['signup','submit_signup','signup_complete']
urlpatterns = patterns('social.views',
*[url('%s/' % view,view) for view in VIEWS_LIST]
)
If you want to make signup process of multiple steps than you can user Django form wizard. In this way you don't need to change url for every signup step. The URL will look like this:
url(r'^signup/$', SignupWizard([SignupForm_1, SignupForm_2, SignupFormComplete]) ),
Check the form wizard documentation.