Search code examples
reactjsdjangoformsdjango-modelsdjango-views

raise e.__class__( ValueError: Field 'id' expected a number but got 'face picture from actor'


in windows 10 , i'm using react-router-dom 5.2.0 and react-redux 7.2.5 and react 17.0.2 and axios 0.21.4 and WebStorm 2023.1.3 IDE and PyCharm Community Edition 2023.2 and djangorestframework==3.14.0 and Django==4.2.4 and djangorestframework-simplejwt==5.3.0

  1. frontend

Consider - manager_room.js:

 {loadingGetProductCategories ? <Loader /> : errorGetProductCategories ? <div className="alert alert-danger" >{errorGetProductCategories}</div>:productCategoriesRedux ? <div className="mb-3">
                                <div className="form-label" htmlFor="categories">select category</div>
                                <select className="form-select" id="categories" value={category} options={productCategoriesRedux} onChange={(e) => handleChangeNormalSelect(e)} multiple>
                                    {productCategoriesRedux && productCategoriesRedux.map && productCategoriesRedux.map(category => (

                                            <option value={category.title}>{category.title}</option>

                                    ))}
                                </select>


                            </div>:""}

2.backend

Consider - product_views.py:

@api_view(http_method_names=['POST'])
@csrf_exempt
@permission_classes([IsAdminUser])
def upload_new_product(request):
    try:
        data = request.data
        file = request.FILES
        id = data.get('id')
        CustomUser = get_user_model()
        user = CustomUser.objects.filter(id=id).first()
        print("do")
        reqUser = request.user
        if user == reqUser:
            product = Product.objects.create(user=user, name=data.get('productName'), image=file.get('productImage'), brand=data.get('brand'), description=data.get('description'), rating=data.get('rating'), price=data.get('price'), countInStock=data.get('countInStock'))

            product.categories.set(data.getlist('category'))
            product.save()
            

            srz_data = ProductSerializer(instance=product, many=False)
            return Response(srz_data.data, status=status.HTTP_201_CREATED)
        else:
            return Response({'detail': 'you are not this account\'s user'}, status=status.HTTP_401_UNAUTHORIZED)


    except APIException as err:
        return Response(str(err), status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    else:
        print("Nothing went wrong")
    finally:
        print("The 'try except' is finished")

error is in line product.categories.set(data.getlist('category')) by raise:

 raise e.__class__(
ValueError: Field 'id' expected a number but got 'face picture from actor'.
[03/Jan/2024 13:39:44] "POST /api/v1/products/upload_new_product/ HTTP/1.1" 500 130849

Actually the save category is not saved in manyTmanyField and it shows me the mentioned error

Consider - models.py:

def get_product_image_path(instance, filename):
    base_name = os.path.basename(filename)
    name, ext = os.path.splitext(base_name)
    rand_value = random.randint(1, 9999999999999999999999999999999999999)
    final_name = f"{instance.name}-{instance.brand}-{instance.category}-{rand_value}-imageProduct{ext}"
    return f"products_images/{instance.category}/{instance.brand}/{instance.name}/{final_name}"


class Product(models.Model):
    _id = models.AutoField(primary_key=True, editable=False)
    user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.SET_NULL, null=True)
    name = models.CharField(max_length=200, null=True)
    image = models.ImageField(upload_to=get_product_image_path, null=True, blank=True)
    brand = models.CharField(max_length=200, null=True, blank=True)
    category = models.CharField(max_length=200, null=True, blank=True)
    description = models.TextField(null=True, blank=True)
    rating = models.IntegerField(null=True, blank=True)
    numReviews = models.IntegerField(null=True, blank=True, default=0)
    price = models.IntegerField(null=True, blank=True)
    countInStock = models.IntegerField(null=True, blank=True, default=0)
    createdAt = models.DateTimeField(auto_now_add=True)
    likes = models.IntegerField(null=True, blank=True, default=0)
    categories = models.ManyToManyField(ProductCategory, blank=True)

    def __str__(self):
        return f"{str(self.name)} - {self.createdAt}"

    class Meta:
        verbose_name = "product"
        verbose_name_plural = "products"

Note : i guess this field categories = models.ManyToManyField(ProductCategory, blank=True) is the center of the error.

I searched most of the questions in this forum and Google, but I didn't find the answer. Please answer me. I hope I don't encounter a typo error.


Solution

  • The problem is in how you send category data, django orm expect id but you are sendig categories name change it to id. If still want to send names try this:

           category_names = data.getlist('category')
            categories = [ProductCategory.objects.get_or_create(title=category)[0] for category in category_names]
    
            product.categories.set(categories)
            product.save()