Django:从views.py在两个应用之间重定向

问题描述

有两个应用程序:app_userapp_testapp_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);
    }

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...