问题描述
有两个应用程序:app_user
和app_test
。
app_user
包含一个login.html
(带有自定义登录表单)。使用JS中的POST请求来实现登录,该请求在api_login
中调用函数app_user.views.py
。
这是我非常简单的登录功能(用于测试):
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)
这很好用,但是我想在登录为时从http://localhost:8000/login/
(由app_user
包含)重定向到http://localhost:8000/test/
(由app_test
包含)成功。
我的主要网址格式(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'),]
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'),]
app_test
中的网址模式
from django.urls import path
from . import views
urlpatterns = [
path('',views.view_test,name='test-home'),]
JS设置:
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,onError) {
let request = new XMLHttpRequest();
request.open(method,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));
}
}
api_login
中的重定向不适用于:
redirect('test-home')
或redirect('app_test:test-home')
(为此,我在app_name = 'app_test'
中添加了app_test.py
。那么如何在api_login
中进行两个应用之间的重定向?
解决方法
您获得的用于有效登录的响应将是url'app_test:test-home'的html页面。您可以在浏览器开发人员工具中进行检查。即使是有效的登录,也需要获取请求的JsonResponse。在响应中添加重定向URL,并使用js进行重定向。
使用reverse()
创建重定向URL。 docs
如果您需要在代码中使用类似于url模板标记的
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)
在js中重定向检查响应数据
if( 'redirect' in data) {
window.location = data['redirect'];
}
您可以在以下任一位置添加
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);
}