如何将 QuerySet 实例传递给序列化程序?

how to pass a QuerySet instance to serializer?

我正在使用原始 sql(正在使用 orm)来获取产品,但出现此错误

Got AttributeError when attempting to get a value for field `name` on serializer `ProductSerializer`.
The serializer field might be named incorrectly and not match any attribute or key on the `tuple` 
instance.
Original exception text was: 'tuple' object has no attribute 'name'.

这是获取函数:

def get(self, request, store_id, format=None):
    with connection.cursor() as cursor:
        user = request.user
        check_auth = get_object_or_404(
            Store, id=store_id, owner_id=user.id)
        if check_auth != None:
            connection.cursor()
            cursor.execute('SELECT * FROM products')
            products = cursor.fetchall()
            serializer = ProductSerializer(products, many=True)
            return Response(serializer.data)
    raise Http404

这是序列化器 class:

class ProductSerializer(serializers.ModelSerializer):
id = serializers.IntegerField(read_only=True)
category = CategorySerializer()

class Meta:
    model = Product
    fields = ['id', 'store_id', 'name', 'summary',
              'description', 'category', 'main_image', 'price', 'offer_price', 'cost', 
    'available_quantity']

Django ModelSerializer 仅适用于从模型中检索到的 QuerySet 对象。使用连接对象执行查询将得到 Python 本机数据类型的结果,例如 ListTuple,其中 ModelSerializer 将不起作用。因此,在这种情况下,cursor.fetchall() 将给出 tuples 的列表,每个元组由一个关系数据库行组成。因此,要序列化这些数据类型而不是 ModelSerializer,只需使用 Serializer。下面的代码片段将详细介绍 SerializerMethodField.

View.py

class RawQueryDjango(APIView):
    def get(self, request):
        from django.db import connection
        cursor = connection.cursor()
        cursor.execute('select * from products_usermodel')
        res = cursor.fetchall()
        serializer = RawQuerySerializer(res, many=True)
        print(serializer.data)
        return Response({'detail': serializer.data})

Serializer.py

from rest_framework.serializers import Serializer, ModelSerializer, SerializerMethodField


class RawQuerySerializer(Serializer):
    name = SerializerMethodField()
    last_name = SerializerMethodField()

    def get_name(self, obj):
        return obj[1]

    def get_last_name(self, obj):
        return obj[2]    # index value at which last_name in tuple

这将给出以下响应。在原始查询执行中,没有与模型进行交互。

{
    "detail": [
        {
            "name": "abc",
            "last_name": "sadfasd"
        },
        {
            "name": "asasasd",
            "last_name": "werwe"
        },
        {
            "name": "asdafa",
            "last_name": "1231weasd"
        },
        {
            "name": "sh",
            "last_name": "patil"
        }
    ]
}