SAIF AHMED ANIK
SAIF AHMED ANIK

Reputation: 865

How to use another serializer only for CREATE response?

I am making a Shop management API. I will try to describe my problem shortly.

When I make a transaction, as a CREATE response I get,

{
    "id": 14,
    "order": 1,
    "shop": 3,
    "product": 2,
    "quantity": 2,
    "bill": 600
}

But I would like to have a response with Product details like below.

{
  "id": 14,
  "order": 1,
  "shop": 3,
  "product": {
    "id": 2,
    "name": "Product 2 for Shop 1",
    "buying_price": 200,
    "selling_price": 300,
    "stock": 34,
    "shop": 3
  },
  "quantity": 2,
  "bill": 600
}

So I tried to change the serializer when self.action is CREATE. But the problem is, now it's showing Product creating fields in my transaction.

Models

class Product(models.Model):
    """Product model"""

    name = models.CharField(max_length=255)
    shop = models.ForeignKey(Shop, on_delete=models.CASCADE)
    buying_price = models.PositiveIntegerField(default=0)
    selling_price = models.PositiveIntegerField(default=0)
    stock = models.PositiveIntegerField(default=0)

    def __str__(self):
        return self.name

class Transaction(models.Model):
    """Model for keeping customer ordered items"""

    order = models.ForeignKey(CustomerTrasnscation, on_delete=models.CASCADE, null=True)
    product = models.ForeignKey(Product, on_delete=models.CASCADE, null=True)
    quantity = models.PositiveIntegerField(default=0)
    bill = models.PositiveIntegerField(default=0)
    shop = models.ForeignKey(Shop, on_delete=models.CASCADE, null=True)

ViewSet

class TransactionViewSet(viewsets.ModelViewSet):

    authentication_classes = (TokenAuthentication,)
    queryset = models.Transaction.objects.all()
    serializer_class = serializers.TransactionSerializer

    def perform_create(self, serializer):
        own_shop = getShop(self.request.user)
        serializer.save(shop=own_shop)

    def get_serializer_class(self):
        if self.action in ["list", "retrieve", "create"]:
            return serializers.Trasnscation_With_ProductDetailSerializer

        return self.serializer_class

Problem

As you can see, instead of showing Products name, it's showing Product creating fields. As you can see, instead of showing Products name, it's showing Product creating fields.

NOTE: Trasnscation_With_ProductDetailSerializer is working absolutely fine on list and retrieve action.

Upvotes: 0

Views: 441

Answers (1)

Harshit garg
Harshit garg

Reputation: 21

You have to override your "create" method as your main serializer will serializers.TransactionSerializer but the response will be generated with serializers.Trasnscation_With_ProductDetailSerializer

def get_serializer_class(self):
    if self.action in ["list", "retrieve"]:
        return serializers.Trasnscation_With_ProductDetailSerializer

    return self.serializer_class

def create(self, request, *args, **kwargs):
    serializer = self.get_serializer(data=request.data)
    serializer.is_valid(raise_exception=True)
    obj = self.perform_create(serializer)

    serializer = serializers.Trasnscation_With_ProductDetailSerializer()(obj)

    headers = self.get_success_headers(serializer.data)
    return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)

Upvotes: 2

Related Questions