[英]Django - ValueError cannot assign - must be a - instance
我相信我明白我的问题来自哪里我只是不知道如何解决它。 问题是我试图保存对产品的评论,但在产品的选择字段中,显示的项目是他们购买的项目。 我通过覆盖表单中的init方法来实现这一点。 我的问题是这个确切的查询它没有给我产品,它给了我被查询的字符串(由于我的模型中的str )。 因此,当我尝试将评论添加到产品时,会抛出此错误。 我的问题是我不知道如何获得产品,因为为了在选择字段中显示我想要显示的内容,我必须给它特定的查询。 任何帮助是极大的赞赏
形式
class ReviewForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
self.request = kwargs.pop('user')
super(ReviewForm, self).__init__(*args, **kwargs)
self.fields['product'].queryset = ShoppingCartOrderItem.objects.filter(user=self.request, ordered=True)
# for item in self.fields['product'].queryset:
# print(item.item)
# print(self.fields['product'].queryset)
class Meta:
model = Review
exclude = ['user', 'date']
widgets = {
'product': forms.Select(attrs={
'class': 'form-control'
}),
'rating': forms.NumberInput(attrs={
'class': 'form-control',
'placeholder': '5.0..'
}),
'comment': forms.Textarea(attrs={
'class': 'form-control'
})
}
看法
class MyOrdersView(LoginRequiredMixin, View):
def get(self, request, *args, **kwargs):
try:
order = ShoppingCartOrder.objects.filter(user=self.request.user, ordered=True)
form = ReviewForm(user=self.request.user)
context = {
'object': order,
'form': form
}
return render(request, 'my_site/my_orders.html', context)
except ObjectDoesNotExist:
messages.warning(request, 'You do not have any orders')
return redirect('all_products')
def post (self, request, *args, **kwargs):
form = ReviewForm(request.POST, user=self.request.user)
if form.is_valid():
test = form.save(commit=False)
test.user = request.user
test.save()
return redirect('starting_page')
return redirect('all_products')
有问题的模型:
class Review(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
product = models.ForeignKey(Product, on_delete=models.SET_NULL, null=True)
rating = models.DecimalField(max_digits=2, decimal_places=1, validators=[MinValueValidator(Decimal('0.1'))])
comment = models.TextField(validators=[MinLengthValidator(10)])
date = models.DateField(auto_now=True)
def __str__(self):
return str(self.user)
class ShoppingCartOrderItem(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
ordered = models.BooleanField(default=False)
item = models.ForeignKey(Product, on_delete=models.CASCADE)
quantity = models.IntegerField(default=1)
def __str__(self):
return f'{self.quantity} of {self.item.name}'
def get_total_order_price(self):
return self.quantity * self.item.price
def get_total_discount_item_price(self):
return self.quantity * self.item.discount_price
def get_final_price(self):
if self.item.discount_price:
return self.get_total_discount_item_price()
return self.get_total_order_price()
class Meta:
verbose_name_plural = 'Order Item(link between)'
在我的表单中,选择字段中的选项基于此查询 self.fields['product'].queryset = ShoppingCartOrderItem.objects.filter(user=self.request,ordered=True)。 根据模型,它返回 {self.item.name} 的字符串 {self.quantity}。 我相信这是我的问题所在,但老实说我可能完全错了,这只是我最好的猜测哈哈。
添加了一张图片试图让我更清楚我的意思,因为我的解释不是最好的
编辑:完整回溯
Environment:
Request Method: POST
Request URL: http://localhost:8000/my-orders/
Django Version: 3.2.4
Python Version: 3.9.1
Installed Applications:
['my_site',
'django_countries',
'crispy_forms',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware']
Traceback (most recent call last):
File "C:\Users\Matthew\Desktop\VScode\e_com\.venv\lib\site-packages\django\core\handlers\exception.py", line 47, in inner
response = get_response(request)
File "C:\Users\Matthew\Desktop\VScode\e_com\.venv\lib\site-packages\django\core\handlers\base.py", line 181, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Users\Matthew\Desktop\VScode\e_com\.venv\lib\site-packages\django\views\generic\base.py", line 70, in view
return self.dispatch(request, *args, **kwargs)
File "C:\Users\Matthew\Desktop\VScode\e_com\.venv\lib\site-packages\django\contrib\auth\mixins.py", line 71, in dispatch
return super().dispatch(request, *args, **kwargs)
File "C:\Users\Matthew\Desktop\VScode\e_com\.venv\lib\site-packages\django\views\generic\base.py", line 98, in dispatch
return handler(request, *args, **kwargs)
File "C:\Users\Matthew\Desktop\VScode\e_com\my_site\views.py", line 349, in post
if form.is_valid():
File "C:\Users\Matthew\Desktop\VScode\e_com\.venv\lib\site-packages\django\forms\forms.py", line 175, in is_valid
return self.is_bound and not self.errors
File "C:\Users\Matthew\Desktop\VScode\e_com\.venv\lib\site-packages\django\forms\forms.py", line 170, in errors
self.full_clean()
File "C:\Users\Matthew\Desktop\VScode\e_com\.venv\lib\site-packages\django\forms\forms.py", line 374, in full_clean
self._post_clean()
File "C:\Users\Matthew\Desktop\VScode\e_com\.venv\lib\site-packages\django\forms\models.py", line 408, in _post_clean
self.instance = construct_instance(self, self.instance, opts.fields, opts.exclude)
File "C:\Users\Matthew\Desktop\VScode\e_com\.venv\lib\site-packages\django\forms\models.py", line 63, in construct_instance
f.save_form_data(instance, cleaned_data[f.name])
File "C:\Users\Matthew\Desktop\VScode\e_com\.venv\lib\site-packages\django\db\models\fields\__init__.py", line 910, in save_form_data
setattr(instance, self.name, data)
File "C:\Users\Matthew\Desktop\VScode\e_com\.venv\lib\site-packages\django\db\models\fields\related_descriptors.py", line 215, in __set__
raise ValueError(
Exception Type: ValueError at /my-orders/
Exception Value: Cannot assign "<ShoppingCartOrderItem: 1 of Bayard defends a bridge over the Garigliano, 1505>": "Review.product" must be a "Product" instance.
ReviewForm
为product
字段创建ShoppingCartOrderItem
对象的查询集。 所以你在那个领域使用了错误的模型。 它需要是Product
模型的查询集
Exception Value: Cannot assign "<ShoppingCartOrderItem: 1 of Bayard defends a bridge over the Garigliano, 1505>": "Review.product" must be a "Product" instance.
这里的错误是告诉您不能将您选择的ShoppingCartOrderItem
分配给Review.product
,因为它不是Product
。
ShoppingCartOrderItem
的item
是一个产品,因此您可以通过执行以下操作来确定某人订购了哪些产品;
def __init__(self, *args, **kwargs):
user = kwargs.pop('user')
# First get a list of the product IDs from the `ShoppingCartOrderItem`
# objects associated with the user passed to the form.
ordered_product_ids = ShoppingCartOrderItem.objects.filter(user=user).values_list('item_id', flat=True)
# Then filter the products by the ordered product IDs so
# they can only select from the products which they ordered.
self.fields['product'].queryset = Product.objects.filter(id__in=ordered_product_ids)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.