在 Django API 中从 PostgreSQL Procedure/Function 获取错误输出

Getting wrong Output from PostgreSQL Procedure/Function in Django API

我已经在 PostgreSQL 中准备好我的数据库及其所有过程。我以前使用 Laravel 作为我的 API 的后端,所有程序都正常工作并返回正确的输出。

我的 Laravel 控制器函数 API 调用之一如下:

public function retrieve() {
    $data = DB::select(DB::raw("SELECT * FROM showallmenuitem()"));
    $status = count($data);

    return $status ? response(['message'=>'Menu item retrieved successfully','data' =>$data],200):response(['message'=>'Failed to retrieve menu item.']);
}

此方法调用showallmenuitem()过程,存储在$data变量中的输出如下:

{
    "message": "Menu item retrieved successfully",
    "data": [
        {
            "meniuid": 1,
            "menuitemsname": "User"
        },
        {
            "meniuid": 2,
            "menuitemsname": "Payment"
        }
    ]
}

但最近我将后端从 Laravel 更改为 Django,因为我的应用程序中需要一些 AI 功能,而我需要的 AI 模型是用 python 编写的。所以我创建了一个简单的视图来从 Django 调用相同的过程。我期待与 Laravel 相同的输出,但 Django 以错误的格式给我输出。我正在使用 psycopg2 作为数据库驱动程序。 这是我的 Django 视图代码:

@csrf_exempt
def retrieve(request):
    if request.method == 'GET':
        with connection.cursor() as cursor:
            cursor.callproc("showallmenuitem")
            results = cursor.fetchall()

        response = {
            'message'       :   'Menu items retrieved successfully',
            'data'          :   results
            }

        return JsonResponse(response, safe=False, status= 200)

我得到以下格式的输出:

{
    "message": "Menu items retrieved successfully",
    "data": [
        [
            1,
            "User"
        ],
        [
            2,
            "Payment"
        ],
    ]
}

Note: I have also tried running execute function instead of callproc as written below and still get the same output.

        with connection.cursor() as cursor:
            cursor.execute("SELECT * FROM showallmenuitem()")
            results = cursor.fetchall()

所以我的问题是如何在 Django 中以正确的 json 格式获得输出,就像我从 Laravel?

得到的一样

默认情况下 psycopg2 returns 一个元组列表,您会看到它被转换为 JSON 作为数组的数组。要更改此设置,请参见此处:

https://docs.djangoproject.com/en/3.0/topics/db/sql/

Executing custom SQL directly

By default, the Python DB API will return results without their field names, which means you end up with a list of values, rather than a dict. At a small performance and memory cost, you can return results as a dict by using something like this:

def dictfetchall(cursor):
    "Return all rows from a cursor as a dict"
    columns = [col[0] for col in cursor.description]
    return [
        dict(zip(columns, row))
        for row in cursor.fetchall()
    ]