43.django里写自定义的sql进行查询

时间:2024-06-10 19:45:09

在Django中,如果你需要编写自定义的SQL查询,可以使用raw()方法。这个方法允许你直接执行原生SQL查询,并将结果转换为Django的模型实例(如果查询与模型相关)。下面是一个如何使用raw()方法执行自定义SQL查询的例子,假设我们基于上面的SQL查询需求:
首先,确保你的模型dAuth_department已经定义好,对应于表dAuth_department。下面的示例假设你有一个名为Department的模型。

1.返回结果集row()

import json
from django.db import connection
from django.http import JsonResponse
from django.views.decorators.http import require_http_methods

@require_http_methods(["GET"])
def get_Department(request):
    search = request.GET.get("search")
    order_by = 'parentDepartmentId' #self.request.GET.get("orderby")
    if search:
        search = "'%"+search +"%'"
        sql_query = """
            SELECT id, departmentName, createTime, remark, status, parentDepartmentId
            FROM dAuth_department
            WHERE departmentName like 
            """
        sql_query = sql_query + search
    else:
        sql_query = """
                    SELECT id, departmentName, createTime, remark, status, parentDepartmentId
                    FROM dAuth_department;
                    """
    print(sql_query)
    # 使用with语句确保游标被正确关闭
    with connection.cursor() as cursor:
        # 执行SQL查询
        cursor.execute(sql_query)

        # 获取查询结果
        rows = cursor.fetchall()

        # 处理结果,例如转换为字典列表
        results = [dict(zip([col[0] for col in cursor.description], row)) for row in rows]# 初始化存放最终结果的列表
        results_total = []

        # 遍历所有结果项,寻找根部门
        for item in results:
            # 如果部门的父部门ID为0,表示这是一个根部门
            if item['parentDepartmentId'] == 0:
                # 初始化该部门的子部门列表
                item['children'] = []
                # 再次遍历所有结果项,寻找该根部门的子部门
                for item2 in results:
                    # 如果部门的父部门ID等于根部门的ID,表示该部门是根部门的子部门
                    if item2['parentDepartmentId'] == item['id']:
                        # 将子部门添加到根部门的子部门列表中
                        item['children'].append(item2)
                # 将根部门及其子部门添加到最终结果列表中
                results_total.append(item)

        # 初始化响应数据字典,用于包含查询结果的编码和数据部分
        response_data = {
            "code": 0,  # 设置响应代码为0,表示成功
            "data": {  # 数据部分包含查询的总数量和结果列表
                "total": len(results_total),  # 计算查询结果的总数量
                "list": results_total  # 将查询结果列表存储到数据部分
            }
        }
    return JsonResponse(response_data)

2.调用django模型的.objects.raw()方法

@require_http_methods(["GET"])
def get_Department2(request):
    search = request.GET.get("search")
    # 自定义SQL查询
    if search:
        search_term = f"%%{search}%%"  # 已经格式化好的搜索关键词
    else:
        search_term = f"%%"  # 已经格式化好的搜索关键词
    # 注意:在实际应用中,应尽量避免字符串拼接来构造SQL以防SQL注入,这里为了演示简化处理
    sql_query = """
        SELECT id, departmentName, createTime, remark, status, parentDepartmentId
        FROM dAuth_department
        WHERE departmentName LIKE %s;
    """
    results_total = []
    item = {}
    # 使用raw()方法执行SQL查询
    # 注意:这里使用了params参数来安全地传递查询参数,防止SQL注入
    departments = Department.objects.raw(sql_query, [search_term])
    print(22222222222)
    # 遍历查询结果
    for department in departments:
        if department.parentDepartmentId == 0:
            # 将模型实例转换为字典
            item = model_to_dict(department)
            item['children'] = []
            for department2 in departments:
                if department2.parentDepartmentId == department.id:
                    item['children'].append(model_to_dict(department2))
            results_total.append(item)



# 初始化响应数据字典,用于包含查询结果的编码和数据部分
    response_data = {
        "code": 0,  # 设置响应代码为0,表示成功
        "data": {  # 数据部分包含查询的总数量和结果列表
            "total": len(results_total),  # 计算查询结果的总数量
            "list": results_total  # 将查询结果列表存储到数据部分
        }
    }
    return JsonResponse(response_data)