1

I am working with Django and REST Framework and I am trying to create a get function for one of my Views and running into an error. The basic idea is that I am creating a market which can have multiple shops. For each shop there can be many products. So, I am trying to query all those products which exist in one shop. Once I get all those products I want to send it to my serializer which will finally return it as a JSON object. I have been able to make it work for one product but it does not work for an array of products.

My Product model looks like this:

'''Product model to store the details of all the products'''
class Product(models.Model):

    # Define the fields of the product model
    name = models.CharField(max_length=100)
    price = models.IntegerField(default=0)
    quantity = models.IntegerField(default=0)
    description = models.CharField(max_length=200, default='', null=True, blank=True)
    image = models.ImageField(upload_to='uploads/images/products')
    category = models.ForeignKey(Category, on_delete=models.CASCADE, default=1)    # Foriegn key with Category Model
    store = models.ForeignKey(Store, on_delete=models.CASCADE, default=1)
    
    ''' Filter functions for the product model '''

    # Create a static method to retrieve all products from the database
    @staticmethod
    def get_all_products():

        # Return all products
        return Product.objects.all()

     # Filter the data by store ID:
    @staticmethod
    def get_all_products_by_store(store_id):

        # Check if store ID was passed
        if store_id:
            return Product.objects.filter(store=store_id)

The product serializer that I built is as follows:-

class ProductSerializer(serializers.ModelSerializer):
    class Meta:
        model = Product
        fields = '__all__'

and the view that I created is below

class StoreView(generics.ListAPIView):
    """Store view which returns the store data as a Json file. 
    """

    # Define class variables 
    serializer_class = StoreSerializer

    # Manage a get request 
    def get(self, request):
        
        # Get storeid for filtering from the page
        store_id = request.GET.get('id')
       
        if store_id:
            queryset = Product.get_all_products_by_store(store_id)
            # queryset = Product.get_all_products_by_store(store_id)[0]
        else: 
            queryset = Product.get_all_products()
            # queryset = Product.get_all_products()[0]
            print("QUERYSET", queryset)
        
        return Response(ProductSerializer(queryset).data)

The above view gives me the following error

AttributeError at /market
Got AttributeError when attempting to get a value for field `name` on serializer `ProductSerializer`.
The serializer field might be named incorrectly and not match any attribute or key on the `QuerySet` instance.
Original exception text was: 'QuerySet' object has no attribute 'name'.

If instead queryset = Product.get_all_products_by_store(store_id), I use the line below it where I am only selecting the first option then I get the correct JSON response but if there multiple products then I am not able to serialize. How do I make it work?

2
  • 1
    how does get_all_products_by_category look like? Commented May 16, 2021 at 14:17
  • Sorry that is also like store. I was just using it earlier and forgot to change. I will make that edit actually. Edit: Fixed now. Commented May 16, 2021 at 14:20

2 Answers 2

2

If you want to serialize more than one record, either use ListSerializer instead, or pass many=True the the constructor of ModelSerializer:

return Response(ProductSerializer(queryset, many=True).data)
Sign up to request clarification or add additional context in comments.

2 Comments

Neither of the solutions worked. When I turn my serializer to a ListSerializer then I get the following error AssertionError at /market: 'child' is a required argument. If I pass many=True then I get the following error 'StoreView' should either include a queryset` attribute, or override the get_queryset() method.`. I did get a way to make it work which I am putting in the edit of the question now.
Actually, I got the solution from this. I just had to define queryset outside the get function and then my functions can change it. Thanks!
0

I found the answer thanks to @yedpodtrzitko for giving the direction. I had to make two changes.

  1. Define queryset outside the function
  2. Pass many=True the the constructor of ModelSerializer
class StoreView(generics.ListAPIView):
    """Store view which returns the store data as a Json file. 
    """

    # Define class variables 
    queryset = []
    serializer_class = StoreSerializer

    # Manage a get request 
    def get(self, request):
        
        # Get storeid for filtering from the page
        store_id = request.GET.get('id')
       
        if store_id:
            queryset = Product.get_all_products_by_store(store_id)
        else: 
            queryset = Product.get_all_products()
            print("QUERYSET", queryset)
        
        return Response(ProductSerializer(queryset, many = True).data)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.