Reputation: 1711
There are two apps: app_user
and app_test
.
app_user
contains a login.html
(with custom login forms). The login is realized using a POST request in JS, which calls a function api_login
in app_user.views.py
.
This is my very simple login function (for testing):
def api_login(request):
# Get post data
post = json.loads(request.body)
# Get username and password
username = post.get('username', None)
password = post.get('password', None)
# Returned data object
data = {
"success": False,
"username": username,
}
# Username and password
if username == "" or password == "":
data['success'] = False
return JsonResponse(data)
# Check if input is correct
user = authenticate(username=username, password=password)
if user is not None:
data['success'] = True
login(request, user)
# return JsonResponse(data) <-- No data response, there should be a redirect
return redirect('app_test:test-home')
else:
data['success'] = False
return JsonResponse(data)
This works well but I want to make a redirect from http://localhost:8000/login/
(included by app_user
) to http://localhost:8000/test/
(included by app_test
) when the login was successful.
My main url pattern (urls.py
).
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('test/', include('app_test.urls'), name='app_test'),
path('login/', include('app_user.urls'), name='app_login'),
]
Url pattern from app_user
from django.urls import path
from . import views
urlpatterns = [
path('', views.view_login, name='user-login'),
path('api/login', views.api_login, name='user-api-login'),
]
Url pattern from app_test
from django.urls import path
from . import views
urlpatterns = [
path('', views.view_test, name='test-home'),
]
The JS setup:
function login() {
let url = 'api/login';
let data = {
username: inputUsername.getValue(),
password: inputPassword.getValue()
};
let onSuccess = function (data) {
console.log('>> Success!');
console.log(data);
}
let onServerError = function () {
console.log('>> onServerError!');
console.log(data);
}
let onError = function () {
console.log('>> onError!');
console.log(data);
}
request('POST', url, data, onSuccess, onServerError, onError);
}
function request(method, url, data, onSuccess, onServerError, onError) {
let request = new XMLHttpRequest();
request.open(method, url, true);
request.setRequestHeader("X-CSRFToken", getCookie('csrftoken'));
request.setRequestHeader("Content-type", "application/json")
request.responseType = 'json';
request.onload = function () {
if (request.status >= 200 && request.status < 400) {
// Success!
console.log('Status: ' + request.status);
onSuccess(request.response);
} else {
console.log('Status: ' + request.status);
// We reached our target server, but it returned an error
onServerError(request.response);
}
};
request.onerror = function () {
console.log('Status: ' + request.status);
// There was a connection error of some sort
onError(request.response);
};
if (method === 'GET') {
console.log('>> GET');
request.send();
} else {
console.log('>> POST');
request.send(JSON.stringify(data));
}
}
The redirect in api_login
does not work using:
redirect('test-home')
or redirect('app_test:test-home')
(for this I added app_name = 'app_test'
in app_test.py
. So how can I make a redirect in api_login
between two apps?
Upvotes: 0
Views: 86
Reputation: 2451
The response you get for the valid login will be the html page for the url 'app_test:test-home'. You can check that in the browser developer tools. Need to get the JsonResponse for the request even for a valid login. Add the redirect url in the response and redirect using js instead.
Using reverse()
to create the redirect url. docs
If you need to use something similar to the url template tag in your code
from django.urls import reverse
def api_login(request):
# Get post data
post = json.loads(request.body)
# Get username and password
username = post.get('username', None)
password = post.get('password', None)
# Returned data object
data = {
"success": False,
"username": username,
}
# Username and password
if username == "" or password == "":
data['success'] = False
return JsonResponse(data)
# Check if input is correct
user = authenticate(username=username, password=password)
if user is not None:
data['success'] = True
login(request, user)
data['redirect'] = reverse('test-home') # import reverse from django.urls
return JsonResponse(data) # return response with the redirect url
else:
data['success'] = False
return JsonResponse(data)
In js redirect checking the response data
if( 'redirect' in data) {
window.location = data['redirect'];
}
You can add this either in
if (request.status >= 200 && request.status < 400) {
// Success!
console.log('Status: ' + request.status);
if( 'redirect' in request.response) {
window.location = data['redirect'];
}
onSuccess(request.response);
}
OR
let onSuccess = function (data) {
console.log('>> Success!');
if( 'redirect' in data) {
window.location = data.redirect;
}
console.log(data);
}
Upvotes: 1