Home > database >  Cannot assign "2": "OrderProduct.product" must be a "Product" instance
Cannot assign "2": "OrderProduct.product" must be a "Product" instance

Time:01-17

**Hi everyone I want to move the Cart Items to Order Product Table after payment

First, the products are get from the card item model. Product number is multiplied by product price ,and I got the order model for got the order total

My Cart item were not moved to Order Product table How Can I move them?

I got this error ValueError at /go-to-gatewey/**

enter image description here

ValueError at /go-to-gatewey/ Cannot assign "2": "OrderProduct.product" must be a "Product" instance. Request Method: GET Request URL: http://127.0.0.1:8000/go-to-gatewey/ Django Version: 3.2.9 Exception Type: ValueError Exception Value:
Cannot assign "2": "OrderProduct.product" must be a "Product" instance. Exception Location: E:\English Projects_I Do it\Second_Project\GreatKart_Persian\venv\lib\site-packages\django\db\models\fields\related_descriptors.py, line 215, in set Python Executable: E:\English Projects_I Do it\Second_Project\GreatKart_Persian\venv\Scripts\python.exe

payment function:

def go_to_gateway_view(request,total=0, quantity=0):
cart_items = CartItem.objects.filter(user=request.user)
for cart_item in cart_items:
    total  = (cart_item.product.price * cart_item.quantity)
    quantity  = cart_item.quantity
tax = (2 * total) / 100
grand_total = total   tax
form = OrderForm(request.POST)

data = Order()
data.order_total = grand_total
data.tax = tax

# Generate order number
yr = int(datetime.date.today().strftime('%Y'))
dt = int(datetime.date.today().strftime('%d'))
mt = int(datetime.date.today().strftime('%m'))
d = datetime.date(yr, mt, dt)
current_date = d.strftime("%Y%m%d")  # Like this : 2021 03 05
order_number = current_date   str(data.id)
data.order_number = order_number
data.save()

order = Order.objects.filter(user=request.user, is_ordered=False, order_number=order_number)

 # Move the CartItems to Order Product Table
cart_items = CartItem.objects.filter(user=request.user)
for item in cart_items:
    orderProduct = OrderProduct()
    # orderProduct.order_id = order.id
    # orderProduct.payment = payment
    orderProduct.user_id = request.user.id
    orderProduct.product = item.product_id
    orderProduct.quantity = item.quantity
    orderProduct.product_price = item.product.price
    orderProduct.ordered = True
    orderProduct.save()

    # Reduce the quantity of the sold products
    product = Product.objects.get(id=item.product_id)
    product.stock -= item.quantity
    product.save()

# Clear  Cart
CartItem.objects.get(user=request.user).delete()


# خواندن مبلغ از هر جایی که مد نظر است
amount = data.order_total

# تنظیم شماره موبایل کاربر از هر جایی که مد نظر است
user_mobile_number = '09159150915'  # اختیاری

factory = bankfactories.BankFactory()

bank = factory.create()  # or factory.create(bank_models.BankType.BMI) or set identifier
bank.set_request(request)
bank.set_amount(amount)
# یو آر ال بازگشت به نرم افزار برای ادامه فرآیند
bank.set_client_callback_url('/callback-gateway/')
bank.set_mobile_number(user_mobile_number)  # اختیاری

# در صورت تمایل اتصال این رکورد به رکورد فاکتور یا هر چیزی که بعدا بتوانید ارتباط بین محصول یا خدمات را با این
# پرداخت برقرار کنید.
bank_record = bank.ready()

# هدایت کاربر به درگاه بانک
return bank.redirect_gateway()

Order Model:

class Order(models.Model):
STATUS=(
    ('New','New'),
    ('Accepted','Accepted'),
    ('Completed','Completed'),
    ('Cancelled','Cancelled'),
)

user = models.ForeignKey(Account,on_delete=models.SET_NULL,null=True,verbose_name='یوز سفارش دهنده ')
payment = models.ForeignKey(Payment,on_delete=models.SET_NULL,blank=True,null=True,verbose_name='نوع پرداخت ')
order_number =models.CharField(max_length=20,verbose_name='شماره ی سفارش ')
first_name =models.CharField(max_length=50,verbose_name='نام ')
last_name =models.CharField(max_length=50,verbose_name='نام خانوادگی ')
phone =models.CharField(max_length=15,verbose_name='همراه ')
email =models.EmailField(max_length=50,verbose_name='ایمیل ')
address_line_1 =models.CharField(max_length=50,verbose_name='آدرس اول ')
address_line_2 =models.CharField(max_length=50,blank=True,verbose_name='آدرس دوم ')
country =models.CharField(max_length=50,verbose_name='کشور ')
state =models.CharField(max_length=50,verbose_name='دولت ')
city =models.CharField(max_length=50,verbose_name=' شهر ')
order_note =models.CharField(max_length=100,blank=True,verbose_name='یادداشت سفارش ')
order_total = models.FloatField(verbose_name='جمع سفارش')
tax = models.FloatField(verbose_name='مالیات ')
status =models.CharField(max_length=10, choices=STATUS,default='New',verbose_name='وضعیت محصول ')
ip =models.CharField(blank=True,max_length=20,verbose_name='آی پی کاربر ')
is_ordered= models.BooleanField(default=False,verbose_name='سفارش داده شده است  ')
created_at =models.DateTimeField(auto_now_add=True,verbose_name='تاریخ ایجاد ')
updated_at = models.DateTimeField(auto_now=True,verbose_name='تاریخ آپدیت ')

Cart Item model :

class CartItem(models.Model):
user      =models.ForeignKey(Account,on_delete=models.CASCADE ,null=True)
product   =models.ForeignKey(Product,on_delete=models.CASCADE,verbose_name='محصول ')
variations =models.ManyToManyField(Variation,blank=True,verbose_name='تنوع محصول با کدام آیتم')
cart      =models.ForeignKey(Cart,on_delete=models.CASCADE,verbose_name='سبد خرید ',null=True)
quantity  =models.IntegerField(verbose_name='تعداد ')
is_active =models.BooleanField(default=True,verbose_name='فعال/غیرفعال ')

and Order Product Model :

class   OrderProduct(models.Model):
order   = models.ForeignKey(Order,on_delete=models.CASCADE,verbose_name='سفارش ')
payment =models.ForeignKey(Payment,on_delete=models.SET_NULL, blank=True, null=True,verbose_name='نوع پرداخت ')
user =models.ForeignKey(Account,on_delete=models.CASCADE,verbose_name='یوز سفارش دهنده ')
product =models.ForeignKey(Product,on_delete=models.CASCADE,verbose_name='محصول سفارش داده ')
variation =models.ForeignKey(Variation,on_delete=models.CASCADE,verbose_name='تنوع محصول ')
color =models.CharField(max_length=50,verbose_name='رنگ محصول ')
size =models.CharField(max_length=50,verbose_name='سایز محصول ')
quantity =models.IntegerField(verbose_name='تعداد محصول ')
product_price =models.IntegerField(verbose_name='قیمت محصول ')
ordered =models.BooleanField(default=False,verbose_name='سفارش داده شده ')
created_at =models.DateTimeField(auto_now_add=True,verbose_name='تاریخ ایجاد ')
updated_at =models.DateTimeField(auto_now=True,verbose_name='تاریخ آپدیت ')

Which part is wrong? My Cart item were not moved to Order Product table How Can I move them

CodePudding user response:

from the error message the problem is here:

orderProduct.product = item.product_id

it looks like you have in your OrderProduct model something like:

OrderProduct(models.Model):
   ...
   porduct = models.ForeignKey(Product, ....)

That means you need to assign a Product instance, not instance->id

You could change your CartItem model to

CartItem(models.Model):
   ...
   product = models.ForeignKey(Product, ....)

and then modify above to

orderProduct.product = item.product

If this does not help you, please post your models CartItem and OrderProduct

CodePudding user response:

Without seeing the OrderProduct and CartItems classes, the answers you'll receive are likely to be incomplete. However, I'll try to help point you in the right direction.

The issue is this line:

    orderProduct.product = item.product_id

It looks like you've set up your OrderProduct.product member to be a relationship to your Product class. item.product_id, however, is an integer.

There are a few possible solutions to this:

  • You may have set up an OrderProduct.product_id field or similar, which is an integer ID for the related table. If you have, you can set that field to the integer value item.product_id.
    • I personally would use this approach, since it prevents data races when processing multiple requests.
  • If your CartItem has a similar relationship set up with Product, for example under CartItem.product, you could assign that to OrderProduct.product instead, with orderProduct.product = item.product.
    • Alternatively, you could query the Product table for the relevant product, with product = Product.objects.get(id=item.product_id) or similar. Then, you can attempt to assign that object with orderPRoduct.product = product.
    • The issue with this method is it introduces a data race, and adds no more guarantees. You might query the Product in one request, then another request (or application!) might delete the Product from the database, then you attempt to save your orderProduct object, producing an error.
      • The exact same error will occur with the method I would use above, both if the product doesn't exist and if the product existed when querying and was removed. It's better to attempt the insert, then check for an error, than to query, attempt the insert, then have to check for an error anyway.
  •  Tags:  
  • Related