Abid Mehmood
Abid Mehmood

Reputation: 145

Django/RestFramework: how to get data from model that has on foreign key in it

I have two models as

class Shops(models.Model):
    shopkeeper = models.ForeignKey(Shopkeeper, on_delete=models.CASCADE)
    name = models.CharField(max_length=250)
    category = models.CharField(max_length=250)
    contactNumber = models.IntegerField()
    address = models.CharField(max_length=500)
    dateCreated = models.DateTimeField(auto_now_add=True)

and

class Product(models.Model):
    productsubcategory = models.ForeignKey(ProductSubCategory, on_delete=models.CASCADE)
    shop = models.ForeignKey(Shops, on_delete=models.CASCADE)
    title = models.CharField(max_length=250)
    price = models.IntegerField()
    image = models.FileField(null=True)
    detail = models.TextField()
    quantity = models.IntegerField()
    dateCreated = models.DateTimeField(auto_now_add=True)

I have made serializer class for product model. And I want to write a View which should return products of a specific shop. My view is as follow,

class ShopkeeperProductAPIView(generics.GenericAPIView):
    def get(self,request,shop_id):
        products = Product.objects.get(shop=shop_id)
        products_serializer = ProductSerializer(products, many=True)
        return Response(products_serializer.data)

and my url is as follow,

path('shops/products/<int:shop_id>', views.ShopkeeperProductAPIView.as_view())

Please help me out.

Upvotes: 2

Views: 102

Answers (2)

Grigoriy Mikhalkin
Grigoriy Mikhalkin

Reputation: 5573

Is there any reason why, from all tools that DRF provides, you are using only serializers? Here's how I would created products endpoint. In viewsets.py:

class ShopkeeperProductViewSet(viewsets.ViewSet):

    def list(self, request):
        queryset = Product.objects.all()
        serializer = ProductSerializer(queryset, many=True)
        return Response(serializer.data)

    def retrieve(self, request, pk=None):
        queryset = Product.objects.filter(shop=pk)
        serializer = ProductSerializer(queryset, many=True)
        return Response(serializer.data)

And in urls.py:

shops_router = DefaultRouter()
router.register(r'products', ShopkeeperProductViewSet, base_name='product')
urlpatterns = [
    ...,
    url(r'^shops/', include(shops_router.urls)),
]

Upvotes: 1

Bulva
Bulva

Reputation: 1248

You can't use:

products = Product.objects.get(shop=shop_id)

It will return only one product because you used get() method. You have to used filter() and many=True in serializer.

So the code will look like:

class ShopkeeperProductAPIView(generics.GenericAPIView):
    def get(self,request,shop_id):
        products = Product.objects.filter(shop=shop_id)
        products_serializer = ProductSerializer(products, many=True)
        return Response(products_serializer.data)

Upvotes: 1

Related Questions