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
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.
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()