Django多店铺添加商品报错:Field 'id'期望数字却得到QuerySet
问题描述
用户创建两个店铺后尝试添加商品时,返回Field 'id'错误;仅创建单个店铺时,操作正常无报错。
views.py 代码
def itemupload(request): user = request.user items = Items.objects.filter(user_id = request.user) try: # store = Store.objects.get(author= user) store = Store.objects.filter(author= user) except Store.DoesNotExist: store = None if request.method =='POST': itemsforms =ItemsForm(request.POST, request.FILES) imageforms = ImageForm(request.POST, request.FILES) file= request.FILES.getlist('image') if all([itemsforms.is_valid(), imageforms.is_valid()]): item = itemsforms.save(commit = False) item.user = request.user item.save() item.store.add(store) for i in file: Images.objects.create(item = item, image =i) return redirect('index') return redirect('itemupload') imageforms =ImageForm() itemsforms = ItemsForm() context = { 'imageforms': imageforms, 'itemsform':itemsforms, 'items':items, } return render(request, 'jijiapp/itemform.html', context)
models.py 代码
class Store(models.Model): name = models.SlugField(unique =True, max_length=50) author = models.ForeignKey(User, on_delete=models.CASCADE, blank=False) create_date = models.DateTimeField(auto_now_add=True, null=True) discription=models.CharField(max_length=5000, null=True, blank=True) location =models.CharField(max_length=5000, null=True, blank=True) logo =models.ImageField(upload_to='logos/', default = '') def __str__(self): return '%s' % (self.name) class Meta: ordering = ['-name'] verbose_name_plural = 'Store' class Items(models.Model): user = models.ForeignKey(User, on_delete = models.CASCADE, null=True, blank=True) store = models.ManyToManyField(Store) title = models.CharField(max_length=10, null=True, blank =True) description = models.CharField(max_length=1000, null=True, blank=True) price = models.CharField(max_length=20, null=True, blank=True) phone = models.CharField(max_length=20, null=True, blank=True) location =models.CharField(max_length=20, null=True, blank=True) post_date = models.DateTimeField(auto_now_add=True, null=True, blank=True) thumbnails =models.ImageField(upload_to='thumbnails/', null=True, blank=True) def __str__(self): return self.title class Meta: ordering =['-post_date',] verbose_name_plural ='Items'
报错信息
System check identified no issues (0 silenced). March 18, 2023 - 05:34:16 Django version 4.0, using settings 'jijiclone.settings' Starting development server at http://127.0.0.1:8000/ Quit the server with CTRL-BREAK. tiis is the <generator object itemupload.<locals>.<genexpr> at 0x00000248939D25F0> and the is <QuerySet [<Store: X-Clusive Store>, <Store: GenFliX Exception Store>]> Internal Server Error: /home/itemupload/ Traceback (most recent call last): File "C:\Users\Christopher\AppData\Local\Programs\Python\Python38\lib\site-packages\django\db\models\fields\__init__.py", line 1822, in get_prep_value return int(value) TypeError: int() argument must be a string, a bytes-like object or a number, not 'QuerySet' The above exception was the direct cause of the following exception: Traceback (most recent call last): File "C:\Users\Christopher\AppData\Local\Programs\Python\Python38\lib\site-packages\django\core\handlers\exception.py", line 47, in inner response = get_response(request) File "C:\Users\Christopher\AppData\Local\Programs\Python\Python38\lib\site-packages\django\core\handlers\base.py", line 181, in _get_response response = wrapped_callback(request, *callback_args, **callback_kwargs) File "C:\Users\Christopher\jijiclone\jijiapp\views.py", line 74, in itemupload item.store.add(store) File "C:\Users\Christopher\AppData\Local\Programs\Python\Python38\lib\site-packages\django\db\models\fields\related_descriptors.py", line 949, in add self._add_items( File "C:\Users\Christopher\AppData\Local\Programs\Python\Python38\lib\site-packages\django\db\models\fields\related_descriptors.py", line 1125, in _add_items target_ids = self._get_target_ids(target_field_name, objs) File "C:\Users\Christopher\AppData\Local\Programs\Python\Python38\lib\site-packages\django\db\models\fields\related_descriptors.py", line 1072, in _get_target_ids target_ids.add(target_field.get_prep_value(obj)) File "C:\Users\Christopher\AppData\Local\Programs\Python\Python38\lib\site-packages\django\db\models\fields\related.py", line 998, in get_prep_value return self.target_field.get_prep_value(value) File "C:\Users\Christopher\AppData\Local\Programs\Python\Python38\lib\site-packages\django\db\models\fields\__init__.py", line 1824, in get_prep_value raise e.__class__( TypeError: Field 'id' expected a number but got <QuerySet [<Store: X-Clusive Store>, <Store: GenFliX Exception Store>]>. [18/Mar/2023 05:35:26] "POST /home/itemupload/ HTTP/1.1" 500 94474
问题原因与修复
核心问题
store = Store.objects.filter(author= user)返回的是QuerySet对象(多个店铺的集合),而item.store.add()方法需要传入单个模型实例、实例ID,或者用*解包后的QuerySet。单个店铺时Django做了隐式兼容,多个店铺时直接传入QuerySet会触发类型错误,因为方法无法解析整个集合作为参数。
修复方法
将item.store.add(store)改为item.store.add(*store),用*操作符解包QuerySet中的所有店铺实例,即可正确关联多个店铺到商品。
同时,原代码中try-except块对filter()无效(filter()无匹配时返回空QuerySet,不会抛出Store.DoesNotExist异常),可删除多余的异常处理,简化代码:
修改后的关键代码片段:
# 替换原try-except块,直接获取用户所有店铺 store = Store.objects.filter(author=user) # ... if all([itemsforms.is_valid(), imageforms.is_valid()]): item = itemsforms.save(commit=False) item.user = request.user item.save() # 用*解包QuerySet,批量添加关联店铺 item.store.add(*store) for i in file: Images.objects.create(item=item, image=i) return redirect('index')
额外建议
如果业务需要让用户手动选择商品归属的店铺,可在ItemsForm中添加store字段,让用户提交表单时直接选择,无需自动关联所有店铺,更符合实际使用场景。
内容的提问来源于stack exchange,提问作者Wilfred Mathias
相关产品推荐
相关产品推荐

