0

I've just built a Item (product) model for my project's eCommerce page, an ItemDetailsView which returns individual items and an ItemApiView which is meant to create/retrieve/update/delete. When I make a get request to get ItemApiView I expect it to return a full list of items in my database. However, I am getting the following error:

AttributeError: Got AttributeError when attempting to get a value for field `name` on serializer `ItemSerializer`. 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'.

"name" is a field in my Item model. Here is the full model:

class Item(BaseModel):
    """
    Item that can be purchased
    """

    name = models.CharField(max_length=150)
    description = models.TextField(blank=True)
    price = models.DecimalField(max_digits=4, decimal_places=2)
    image = models.ImageField(upload_to="images/", default="images/default.png")
    category = models.ForeignKey(Category, on_delete=models.PROTECT, null=True)
    is_active = models.BooleanField(default=True)
    quantity = models.IntegerField(null=True, blank=True, default=0)
    discount = models.FloatField(default=0.0)
    created = models.DateTimeField(auto_now_add=True)
    updated = models.DateTimeField(auto_now=True)

    class Meta:
        verbose_name_plural = "Products"
        ordering = ("-created",)

    def get_absolute_url(self):
        return reverse("store:product_detail", args=[self.slug])

    def __str__(self):
        return "{}".format(self.name)

Here is the ItemApiView. Only the "Get" method corresponds to my specific problem but I included the full view because I am open to critiques on the put/post/delete methods which I have not yet tested:

class ItemApiView(APIView):
    """
    API endpoint to retrieve, create and update
    """

    @limits(settings.RATE_LIMIT_REQUESTS, settings.RATE_LIMIT_DURATION)
    def get(self, request):
        """Return all items"""

        print("request", request)

        try:
            items = Item.objects.all()
            serialized_data = ItemSerializer(items)
        except:
            return Response({"message": "No items exist"}, status=status.HTTP_404_NOT_FOUND)

        return Response(serialized_data.data)

    @limits(settings.RATE_LIMIT_REQUESTS, settings.RATE_LIMIT_DURATION)
    def put(self, request):
        """Update item info"""
        item_id = request.data["item_id"]

        try:
            item = Item.objects.get(id=item_id),
            id=request.data["id"],
            name=request.data["name"],
            price=request.data["price"],
            is_active=request.data["is_active"],
            description=request.data["description"],
            discount=request.data["discount"],
            image=request.data["image"],
            quantity=request.data["quantity"],
            category=request.data["category"],
        except Item.DoesNotExist:
            return Response(status=status.HTTP_404_NOT_FOUND)

        if item.name != name:
            item.name = name
        elif item.description != description:
            item.description = description
        elif item.price != price:
            item.price = price
        elif item.is_active != is_active:
            item.is_active = is_active
        elif item.discount != discount:
            item.discount = discount
        elif item.quantity != quantity:
            item.quantity = quantity
        elif item.category != category:
            item.category = category

        item.save()

        return Response(ItemSerializer(item).data)

    def delete(self, request):
        """Delete item"""

        item_id = request.data["item_id"]

        try:
            item = Item.objects.get(id=item_id)
        except Item.DoesNotExist:
            return Response(status=status.HTTP_404_NOT_FOUND)

        item.delete()

        return Response(status=status.HTTP_200_OK)

    @limits(settings.RATE_LIMIT_REQUESTS, settings.RATE_LIMIT_DURATION)
    def post(self, request):
        """Create item"""

        item = Item.objects.create(
            id=request.data["id"],
            name=request.data["name"],
            price=request.data["price"],
            is_active=request.data["is_active"],
            description=request.data["description"],
            discount=request.data["discount"],
            image=request.data["image"],
            quantity=request.data["quantity"],
            category=request.data["category"]

        )

        Event.objects.create(
            user=user,
            event_type=Event.ITEM_CREATE,
            payload={
                "id": item.id,
                "name": item.name,
                "price": item.price,
                "is_active": item.is_active,
                "description": item.description,
                "discount": item.discount,
                "image": item.image,
                "quantity": item.quantity,
                "category": item.category,
            },
        )

        return Response(ItemSerializer(item).data)

and finally here is the ItemSerializer:

class ItemSerializer(serializers.ModelSerializer):
    """
    Item Serializer
    """

    class Meta:
        model = Item
        fields = "__all__"
1

1 Answer 1

1

try to add many=True, when creating list serializer

class ItemApiView(APIView):
    ...
    def get(self, request):
        ...

        try:
            items = Item.objects.all()
            serialized_data = ItemSerializer(items, many=True)
        ...
Sign up to request clarification or add additional context in comments.

1 Comment

You saved my evening :) It works without many=True on my local instance, but not on the server

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.