简体   繁体   中英

Object of type 'ListSerializer' is not JSON serializable

I want to get all customer data and responses and also remarks. This is model.py

class Customer(models.Model):

name = models.CharField(max_length=200)
email_address = models.CharField(max_length=200)
phone_number = models.CharField(max_length=20)
age = models.SmallIntegerField(default=14)
remarks = models.ManyToManyField(Remark,null=True,blank=True)
created_at = models.DateTimeField(auto_now_add=True)

def __str__(self):
    return str(self.id)


class Response(models.Model):

question = models.ForeignKey(Question)
customer = models.ForeignKey(Customer)
response_text = models.CharField(max_length=100, null=True, blank=True)
created_at = models.DateTimeField(auto_now_add=True)
uuid = models.UUIDField()

def __str__(self):
    return str(self.id)

This is serializers.py

class ResponseSerializer(ModelSerializer):
  class Meta:
    model = Response
    fields = '__all__'

class RemarksSerializer(ModelSerializer):
  class Meta:
    model = Remark
    fields = '__all__'

class CustomerInformationSerializer(ModelSerializer):
  remarks = RemarksSerializer(many=True)
  responses = serializers.SerializerMethodField()

  def get_responses(self, obj):
    responses = Response.objects.filter(customer=obj)
    return ResponseSerializer(responses, many=True)

  class Meta:
    model = Customer
    fields = ('name', 'email_address', 'phone_number', 'age', 'remarks', 'responses')

This is services.py

def customer_information(company_id=1):
  cus = Customer.objects.filter(remarks__company_id=company_id)
  return CustomerInformationSerializer(cus, many=True).data

This is views.py

class CustomerInformationView(APIView):
  def get(self, request):
     company_id = request.GET.get('company_id', 1)
     resp = {'data': customer_information(company_id)}
     return Response(data=resp, status=status.HTTP_200_OK)

This is url.py

 url(r'^customer/$', CustomerInformationView.as_view()),

I'm having this problem. How can I solve this. Kindly guide me.

SIDE NOTE

First, let me point you to a resource that I think is GREAT for anything dealing with Django REST Framework:

Classy Django REST Framework . It is a fantastic resource because you can easily dig right into the source code to see how you may or may not need to override default operations.

MY ANSWER

What I suggest is that instead of using the APIView , you useListAPIView .

It would look something like this:

from rest_framework.generics import ListAPIView


class Customer(models.Model):
    name = models.CharField(max_length=200)
    email_address = models.CharField(max_length=200)
    phone_number = models.CharField(max_length=20)
    age = models.SmallIntegerField(default=14)
    remarks = models.ManyToManyField(Remark,null=True,blank=True)
    created_at = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return str(self.id)


class Response(models.Model):
    question = models.ForeignKey(Question)
    customer = models.ForeignKey(Customer, related_name='responses')
    response_text = models.CharField(max_length=100, null=True, blank=True)
    created_at = models.DateTimeField(auto_now_add=True)
    uuid = models.UUIDField()

    def __str__(self):
        return str(self.id)


class ResponseSerializer(ModelSerializer):
    class Meta:
        model = Response
        fields = '__all__'


class RemarksSerializer(ModelSerializer):
    class Meta:
        model = Remark
        fields = '__all__'


class CustomerInformationSerializer(ModelSerializer):
    remarks = RemarksSerializer(many=True)
    responses = ResponseSerializer(many=True)

    class Meta:
        model = Customer
        fields = ('name', 'email_address', 'phone_number', 'age', 'remarks', 'responses')


class CustomerInformationView(ListAPIView):
    queryset = Customer.objects.all()
    serializer_class = CustomerInformationSerializer
    lookup_field = 'remarks__company'

Note the change that I made by adding related_name to the customer field on your Response model. See Django documentation for more information on related_name . In short, it adds responses as a field name on your Customer model so that you can travel backwards through that relationship.

This is not tested, but this should be a better strategy to do what you want without having to have a get_responses method, or a services.py .

用views.py中的Response(serializer.data)替换Response(serializer)

在您的视图中获取函数应该返回响应数据,插入响应数据。

Some there might be error because of missing "/" at the end of path like "event-api"=incorrect and "event-api/" correct. That worked for me. Hope you also have same problem. Incorrect: path('event-api',views.event_view,name="event-view") Correct: path('event-api/',views.event_view,name="event-view")

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM