繁体   English   中英

Django - ValueError 无法分配 - 必须是 - 实例

[英]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.

ReviewFormproduct字段创建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

ShoppingCartOrderItemitem是一个产品,因此您可以通过执行以下操作来确定某人订购了哪些产品;

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM