Search code examples
pythondjangodjango-modelsdjango-rest-frameworkdjango-serializer

How to fetch data from other table django rest framework


I have a cartmodel, cartitem and offlinecheckout model. I want to display cartitem instead of cartmodel id, I want to display all the cartitem data which have cart_id = offlinecheckout cart_id. But I got this response.

I tried a lot but didn't get. Anybody will please help me.

I got this result

views.py

class GetAPI(APIView):
    def get(self, request,  *args, **kwargs):
        serializer = OfflineSerializer()
        return Response(serializer.data)

models.py

class OfflineCheckOut(models.Model):
    billing_name = models.CharField(max_length=254)
    billing_phone_no = models.CharField(max_length=15)
    user = models.ForeignKey('accounts.User', on_delete=models.CASCADE)
    cart = models.ForeignKey('cart.CartModel', on_delete=models.CASCADE)
    cartitem = models.ManyToManyField(CartItem, blank=True)
    # time_slot = models.ForeignKey('category.TimeSlot', on_delete=models.CASCADE)
    address = models.ForeignKey('cart.CustomerAddress', on_delete=models.CASCADE)
    status_choice = [
        ('0', 'Offline'),
        ('1', 'Online')
    ]
    status = models.CharField(max_length=3, choices=status_choice, default=0)
    # date = models.DateField()
    date = models.DateField()
    time_slot = models.ForeignKey('category.TimeSlot', on_delete=models.SET_NULL, null=True, blank=True)
    order_id = models.CharField(max_length=254, blank=True)
    # date = models.DateField()
    razorpay_payment_id =models.CharField(max_length=254, blank=True)
    razorpay_signature = models.CharField(max_length=254, blank=True)
    paid = models.BooleanField(default=False)
    service = models.ForeignKey('service.ServiceProvider', on_delete=models.SET_NULL, null=True, blank=True)

class CartModel(models.Model):
    user = models.ForeignKey('accounts.User', on_delete=models.CASCADE)
    status_choice = [
        ('1', 'open'),
        ('2', 'closed')
    ]
    status = models.CharField(max_length=2, choices=status_choice, default=1)
    validated = models.BooleanField(default=False)

    
    def __str__(self):
        return self.user.username
    
    @property
    def total_price(self):
        return self.cartitem_set.aggregate(
            total_price=Sum(F('quantity') * F('price'))
        )['total_price'] or Decimal('0')
 


class CartItem(models.Model):
    cart = models.ForeignKey('CartModel', on_delete=models.CASCADE)
    user = models.ForeignKey('accounts.User', on_delete=models.CASCADE)
    service = models.ForeignKey('accounts.SubCategory', on_delete=models.CASCADE)
    defects = models.ForeignKey('category.Defects', on_delete=models.CASCADE)
    quantity = models.IntegerField(default=1)
    price = models.IntegerField()
    created_on = models.DateTimeField(auto_now_add=True)
    updated_on = models.DateTimeField(auto_now_add=True)
    order_placed = models.BooleanField(default=False)

serializers.py

class OfflineSerializer(serializers.ModelSerializer):
    def total(self, obj):
        return obj.total
    total = serializers.IntegerField(read_only=True)
    cartitems = CartItemSerializer( read_only=True, many=True)
    class Meta:
        model = OfflineCheckOut
        fields = ['user', 'billing_name','billing_phone_no','cartitem', 'cartitems','cart', 'date', 'time_slot', 'address', 'total']
        extra_fields = ['total', 'cartitems']

Solution

  • You have to put them in a serializer for CartModel. Then OfflineSerializer will use that for cart field.

    class CartModelSerializer(serializers.ModelSerializer):
        cartitem_set = CartItemSerializer(read_only=True, many=True)
    
        class Meta:
            model = CartModel
            fields  = [
                "cartitems_set",
                # other fields here
            ]
    
    
    class OfflineSerializer(serializers.ModelSerializer):
        def total(self, obj):
            return obj.total
        total = serializers.IntegerField(read_only=True)
        cart = CartModelSerializer(read_only=True)
    
        class Meta:
            model = OfflineCheckOut
            fields = ['user', 'billing_name','billing_phone_no','cartitem', 'cartitems','cart', 'date', 'time_slot', 'address', 'total']
            extra_fields = ['total', 'cartitems']
    
    

    EDIT: Changed the related name serializer from cartlineitems_set to cartlineitem_set