【问题标题】:How to return a queryset as a JSON response in Django RESTFramework?如何在 Django REST 框架中将查询集作为 JSON 响应返回?
【发布时间】:2020-04-15 05:53:47
【问题描述】:

我试图在 DRF 中将查询集作为 JSON 响应返回,但我总是得到 TypeError Object Not JSON serializable。

我尝试了不同的方法,但都没有奏效。我尝试使用 JSONRenderer 类,也尝试使用 SentSerializer 序列化单个对象。但似乎没有什么能解决问题。我刚开始学习 DRF,所以对我来说有点困惑,并且真的不明白序列化程序是如何工作的,我不确定我是否正确编写或正确使用它们。

# models
...
from django.contrib.auth.models import User

class Sentence(models.Model):
    sent = models.CharField(max_length=255)
    sent_correct = models.CharField(max_length=255, null=True)
    pub_date = models.DateTimeField(default=timezone.now)
    author = models.ForeignKey(User, on_delete=models.CASCADE, null=True, related_name='sentences')

# serializers
...
from django.contrib.auth.models import User

class UserSerializer(serializers.ModelSerializer):
    password = serializers.CharField(write_only=True)
    username = serializers.CharField(max_length=50)

    class Meta:
        model = User
        # Tuple of serialized model fields (see link [2])
        fields = ( "id", "username", "password", )

class SentSerializer(serializers.ModelSerializer):

    sent = serializers.CharField(max_length=255)
    sent_correct = serializers.CharField(max_length=255, required=False)
    author = UserSerializer(read_only=True, required=False)

    class Meta:
        model = Sentence
        fields = (
            'sent', 'sent_correct', 'author'
        )

# views
...
class SentCreateAPIView(APIView):
    serializer_class = SentSerializer
    permission_classes = (IsAuthenticated,)

    def post(self, request):
        ss = Sentence.objects.filter(author=request.user)[0:1]
        ss = list(ss)
        print("sentences " + str(ss))
        serializer = self.serializer_class(data=request.data)
        serializer.is_valid(raise_exception=True)
        vd = serializer.validated_data
        sent_str = vd['sent']
        s = Sentence(sent=sent_str, sent_correct=sent_str)
        s.author = request.user
        print(vd)
        print(request.user)
        s.save()
        sent = nlp(sent_str)
        tokens = [t.text for t in sent] # this list returns successfully

        return Response(
            {   'sent': sent_str,
                'sent_correct': sent_str,
                'tokens': tokens,
                'ss': ss, # this list throws TypeError},
            status=status.HTTP_201_CREATED
        )

【问题讨论】:

    标签: django-rest-framework


    【解决方案1】:

    Jakub Maślanka 在 Facebook 的 Django Python Web 框架组中回答了我的问题。我不得不像这样序列化查询集:

    # views.py 
    ...
    
    return Response(
                {   'sent': sent_str,
                    'sent_correct': sent_str,
                    'tokens': tokens,
                    'ss': SentSerializer(ss, many=True).data},
                status=status.HTTP_201_CREATED
            )
    

    【讨论】:

      【解决方案2】:

      ss -> 字典

      为什么不使用 generics.ListAPIView。 它有 get_query_set 方法 您只需要通过您自己的查询集覆盖该方法 代码越少越好 -> 基于类和框架

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-08-21
        • 2015-03-30
        • 1970-01-01
        • 2016-05-03
        • 1970-01-01
        • 2015-05-08
        相关资源
        最近更新 更多