1

I got AttributeError when attempting to get a value for field client on serializer ClientSerializer.

The serializer field might be named incorrectly and not match any attribute or key on the QuerySet instance.

models.py

class Box(models.Model):
    box = models.IntegerField()
    controller = models.ForeignKey(Controller, related_name='boxes', on_delete=models.CASCADE)

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


class Client(models.Model):
    client = models.CharField(max_length=30)
    cpf = models.IntegerField()
    box = models.OneToOneField(
    
        Box,
        on_delete=models.CASCADE,
        primary_key=True
    )

    def __str__(self):
        return self.client

serializers.py

class ClientSerializer(serializers.ModelSerializer):
    class Meta:
        model = Client
        fields = [
            "id",
            "client",
            "cpf",
            "box",
        ]

class BoxSerializer(serializers.ModelSerializer):
    class Meta:
        model = Box
        fields = [
            "id",
            "box",
            "controller"
        ]

views.py


class ClientViewSet(viewsets.ModelViewSet):
    serializer_class = ClientSerializer
    queryset = Client.objects.all()

    def list(self, request, store_pk=None, locker_pk=None, controller_pk=None, box_pk=None):
        queryset = Client.objects.filter(box=box_pk, box__controller=controller_pk, box__controller__locker=locker_pk, box__controller__locker__store=store_pk)
        serializer = ClientSerializer(queryset, context={'request': request})
        return Response(serializer.data)

    def retrieve(self, request, store_pk=None, locker_pk=None, controller_pk=None, box_pk=None):
        queryset = Client.objects.filter(box=box_pk, box__controller=controller_pk, box__controller__locker=locker_pk, box__controller__locker__store=store_pk)
        client = get_object_or_404(queryset)
        serializer = ClientSerializer(client, context={'request': request})
        return Response(serializer.data)

I'm trying to get the object client on lockers/1/controllers/1/boxes/1/client/ which is OneToOneField relations with boxes and It's in a nested router I already tried use decorator @action but yet didn't work.

Anyone know why it's not finding the correct object attribute ?

Community
  • 1
  • 1

1 Answers1

2

For a list method you should use many=True parameter when you're creating a new serializer instance:

serializer = ClientSerializer(queryset, context={'request': request}, many=True)

In case of retrieve only one object should be received. Instead of

client = get_object_or_404(queryset)

you should call first(), last() (or most basically and clearly - .get(pk=pk)) on queryset to retrieve only one item from QuerySet. Then you should just execute:

# client is one of elements of your queryset
serializer = ClientSerializer(client, context={'request': request})
rafaljusiak
  • 1,050
  • 1
  • 10
  • 17