'django-tenants: redirecting to tenant url after login raises "NoReverseMatch: 'demo.localhost' is not a registered namespace"
I don't seem to find a way to solve an error happening at the user authentication.
User needs to login at the public website level let's say localhost/login and when he/she is authenticated, I need the user to be redirected in the corresponding sub domain, for example demo.localhost. This is not working for me so far, even after checking some posts about the subject.
Here is the views.py in customers.views where user log in:
def login_view(request):
if request.method == 'POST':
form = AuthenticationForm(request,data=request.POST)
print("form login view")
if form.is_valid():
print("checkpoint")
username = form.cleaned_data.get('username')
password = form.cleaned_data.get('password')
user = authenticate(username=username, password=password)
user = form.get_user()
schema_name = user.schema_name
print(user)
if user is not None:
login(request, user)
url = reverse(schema_name + '.localhost:8000/mydashboard/')
print("url")
return HttpResponseRedirect(url)
else:
print("not working")
form = AuthenticationForm()
context = {
'form': form,
}
return render(request, 'login.html', context)
here is what urls in the core folder:
urlpatterns = [
path('admin/', admin.site.urls),
path('django_plotly_dash/', include('django_plotly_dash.urls')),
path('mydashboard/', include('mydashboard.urls',namespace="mydashboard")),
]
and I have added app_name = 'mydashboard' in mydashboard.urls
Here is the traceback of the error I keep getting:
Internal Server Error: /registration/loginUser
Traceback (most recent call last):
File "/Users/pierre/opt/anaconda3/lib/python3.9/site-packages/django/urls/base.py", line 71, in reverse
extra, resolver = resolver.namespace_dict[ns]
KeyError: 'demo.localhost'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/Users/pierre/opt/anaconda3/lib/python3.9/site-packages/django/core/handlers/exception.py", line 47, in inner
response = get_response(request)
File "/Users/pierre/opt/anaconda3/lib/python3.9/site-packages/django/core/handlers/base.py", line 181, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/Users/pierre/Desktop/simulation_application/customers/views.py", line 65, in login_view
url = reverse(schema_name + '.localhost:8000/mydashboard/')
File "/Users/pierre/opt/anaconda3/lib/python3.9/site-packages/django/urls/base.py", line 82, in reverse
raise NoReverseMatch("%s is not a registered namespace" % key)
django.urls.exceptions.NoReverseMatch: 'demo.localhost' is not a registered namespace
UPDATE:
Remove the reverse and included request.scheme in the url.
def login_view(request):
if request.method == 'POST':
form = AuthenticationForm(request,data=request.POST)
print("form login view")
if form.is_valid():
print("checkpoint")
username = form.cleaned_data.get('username')
password = form.cleaned_data.get('password')
user = authenticate(username=username, password=password)
user = form.get_user()
schema_name = user.schema_name
print(user)
if user is not None:
login(request, user)
print(request.scheme)
url = request.scheme + '://' + schema_name + '.localhost:8000/mydashboard/'
print("url",url)
return HttpResponseRedirect(url)
else:
print("not working")
form = AuthenticationForm()
context = {
'form': form,
}
return render(request, 'login.html', context)
this is still working and output the following error:
response = get_response(request) …
Local vars
/Users/pierre/opt/anaconda3/lib/python3.9/site-packages/django/core/handlers/base.py, line 181, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs) …
Local vars
/Users/pierre/opt/anaconda3/lib/python3.9/site-packages/django/contrib/auth/decorators.py, line 32, in _wrapped_view
return redirect_to_login( …
Local vars
/Users/pierre/opt/anaconda3/lib/python3.9/site-packages/django/contrib/auth/views.py, line 190, in redirect_to_login
return HttpResponseRedirect(urlunparse(login_url_parts)) …
Local vars
/Users/pierre/opt/anaconda3/lib/python3.9/site-packages/django/http/response.py, line 507, in __init__
raise DisallowedRedirect("Unsafe redirect to URL with protocol '%s'" % parsed.scheme) …
Local vars
Unsafe redirect to URL with protocol 'localhost'
Bad Request: /mydashboard/simulations_list
HTTP GET /mydashboard/simulations_list 400 [0.09, 127.0.0.1:50218]
This is strange because the requested url is perfectly working url, registered and accessible without a problem before trying to redirect to it after the login
EDIT #2:
Found out that the above code works when the target url does not require login required
# this does not work
@login_required
def simulationslistView(request,):
return render(request, 'simulations_list.html')
# this works
def simulationslistView(request,):
return render(request, 'simulations_list.html')
I am obviously make sure that the app is secured and can only be accessed by logged in users. Is there a work around to make sure it works?
Solution 1:[1]
reverse is an internal django utility to go from "app name" + ':' + "url friendly name" to "real url". In your example, you're already providing the "real url".
Quit while you're ahead and just do:
if user is not None:
login(request, user)
url = request.scheme + '://' + schema_name + '.localhost:8000/mydashboard/'
print("url")
return HttpResponseRedirect(url)
- Notice no
reverse - Notice the adding of the URL scheme (http/https determined by how the request was originally made)
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
