ValueError:在使用此多对多关系之前,需要具有字段“ id”的值

时间:2019-02-12 10:36:55

标签: python django

我创建了一个数字产品的电子商务应用程序,并在我的产品模型的个人资料模型中创建了ManyToMany关系。

添加多对多字段后,在我的Profile模型中,它阻碍了我创建新的Profile并给出以下错误消息:-

ValueError: needs to have a value for field "id" before this many-to-many relationship can be used.

这是我的模特

class Profile(models.Model):
    date = models.DateTimeField(auto_now_add=True)
    name = models.OneToOneField(settings.AUTH_USER_MODEL,on_delete=models.CASCADE)
    subscribed_products = models.ManyToManyField(Product,related_name='products_subscribed',blank=True)

class Product_activation(models.Model):
    user        = models.ForeignKey(settings.AUTH_USER_MODEL,on_delete=models.CASCADE,null=True,blank=True)
    product     = models.ForeignKey(Product,on_delete=models.CASCADE,related_name='product_activate')
    is_active    = models.BooleanField(default=False)

@receiver(pre_save, sender=Profile)
def product_activation(sender,instance,*args,**kwargs):
    for product in instance.subscribed_products.all():
        if Product_activation.objects.filter(User=instance.Name,product=product).exists():
            pass
        else:
            Product_activation.objects.update_or_create(User=instance.Name,product=product,activate=False,deactivate=True)   


class Product(models.Model):
    title       = models.CharField(max_length=32)
    price       = models.DecimalField(default=10000.00,max_digits=10,decimal_places=2)



class OrderItem(models.Model):
    product = models.OneToOneField(Product, on_delete=models.SET_NULL, null=True)
    is_ordered = models.BooleanField(default=False)
    date_added = models.DateTimeField(auto_now=True)
    date_ordered = models.DateTimeField(null=True)

def __str__(self):
    return self.product.title


class Order(models.Model):
    ref_code        = models.CharField(max_length=15)
    owner           = models.ForeignKey(Profile, on_delete=models.SET_NULL, null=True)
    is_ordered      = models.BooleanField(default=False)
    items           = models.ManyToManyField(OrderItem)
    date_ordered    = models.DateTimeField(auto_now=True)

    def get_cart_items(self):
        return self.items.all()

    def get_cart_total(self):
        return self.items.aggregate(total=Sum('product__price'))['total'] or 0

    def __str__(self):
        return '{0} - {1}'.format(self.owner, self.ref_code)

class Transaction(models.Model):
   profile = models.ForeignKey(Profile, on_delete=models.CASCADE)
   order_id = models.CharField(max_length=120)
   amount = models.DecimalField(max_digits=100, decimal_places=2)
   success = models.BooleanField(default=True)
   timestamp = models.DateTimeField(auto_now_add=True, auto_now=False)

    def __str__(self):
        return self.order_id

我已经在views.py中完成了此操作:

def get_user_pending_order(request):
    # get order for the correct user
    user_profile = get_object_or_404(Profile, Name=request.user)
    order = Order.objects.filter(owner=user_profile, is_ordered=False)
    if order.exists():
        # get the only order in the list of filtered orders
        return order[0]
    return 0

@login_required()
def update_transaction_records(request):
    # get the order being processed
    order_to_purchase = get_user_pending_order(request)

    # update the placed order
    order_to_purchase.is_ordered=True
    order_to_purchase.date_ordered=datetime.datetime.now()
    order_to_purchase.save()

    # get all items in the order - generates a queryset
    order_items = order_to_purchase.items.all()

    # update order items
    order_items.update(is_ordered=True, date_ordered=datetime.datetime.now())

    # Add products to user profile
    user_profile = get_object_or_404(Profile, Name=request.user)

    # get the products from the items
    order_products = [item.product for item in order_items]
    user_profile.subscribed_products.add(*order_products)
    user_profile.save()


    # create a transaction
    transaction = Transaction(profile=request.user.profile,
                        order_id=order_to_purchase.id,
                        amount=order_to_purchase.get_cart_total(),
                        success=True)
    # save the transcation (otherwise doesn't exist)
    transaction.save()

    return redirect(reverse('ecommerce_integration:productlist'))  

TraceBack:

File "C:\Users\HP\myEnv\lib\site-packages\django\core\handlers\exception.py" in inner
  35.             response = get_response(request)

File "C:\Users\HP\myEnv\lib\site-packages\django\core\handlers\base.py" in _get_response
  128.                 response = self.process_exception_by_middleware(e, request)

File "C:\Users\HP\myEnv\lib\site-packages\django\core\handlers\base.py" in _get_response
  126.                 response = wrapped_callback(request, *callback_args, **callback_kwargs)

File "C:\Users\HP\myEnv\lib\site-packages\django\contrib\admin\options.py" in wrapper
  575.                 return self.admin_site.admin_view(view)(*args, **kwargs)

File "C:\Users\HP\myEnv\lib\site-packages\django\utils\decorators.py" in _wrapped_view
  142.                     response = view_func(request, *args, **kwargs)

File "C:\Users\HP\myEnv\lib\site-packages\django\views\decorators\cache.py" in _wrapped_view_func
  44.         response = view_func(request, *args, **kwargs)

File "C:\Users\HP\myEnv\lib\site-packages\django\contrib\admin\sites.py" in inner
  223.             return view(request, *args, **kwargs)

File "C:\Users\HP\myEnv\lib\site-packages\django\utils\decorators.py" in _wrapper
  62.             return bound_func(*args, **kwargs)

File "C:\Users\HP\myEnv\lib\site-packages\django\views\decorators\debug.py" in sensitive_post_parameters_wrapper
  76.             return view(request, *args, **kwargs)

File "C:\Users\HP\myEnv\lib\site-packages\django\utils\decorators.py" in bound_func
  58.                 return func.__get__(self, type(self))(*args2, **kwargs2)

File "C:\Users\HP\myEnv\lib\site-packages\django\utils\decorators.py" in _wrapper
  62.             return bound_func(*args, **kwargs)

File "C:\Users\HP\myEnv\lib\site-packages\django\utils\decorators.py" in _wrapped_view
  142.                     response = view_func(request, *args, **kwargs)

File "C:\Users\HP\myEnv\lib\site-packages\django\utils\decorators.py" in bound_func
  58.                 return func.__get__(self, type(self))(*args2, **kwargs2)

File "C:\Users\HP\myEnv\lib\site-packages\django\contrib\auth\admin.py" in add_view
  100.             return self._add_view(request, form_url, extra_context)

File "C:\Users\HP\myEnv\lib\site-packages\django\contrib\auth\admin.py" in _add_view
  127.         return super().add_view(request, form_url, extra_context)

File "C:\Users\HP\myEnv\lib\site-packages\django\contrib\admin\options.py" in add_view
  1554.         return self.changeform_view(request, None, form_url, extra_context)

File "C:\Users\HP\myEnv\lib\site-packages\django\utils\decorators.py" in _wrapper
  62.             return bound_func(*args, **kwargs)

File "C:\Users\HP\myEnv\lib\site-packages\django\utils\decorators.py" in _wrapped_view
  142.                     response = view_func(request, *args, **kwargs)

File "C:\Users\HP\myEnv\lib\site-packages\django\utils\decorators.py" in bound_func
  58.                 return func.__get__(self, type(self))(*args2, **kwargs2)

File "C:\Users\HP\myEnv\lib\site-packages\django\contrib\admin\options.py" in changeform_view
  1451.             return self._changeform_view(request, object_id, form_url, extra_context)

File "C:\Users\HP\myEnv\lib\site-packages\django\contrib\admin\options.py" in _changeform_view
  1491.                 self.save_model(request, new_object, form, not add)

File "C:\Users\HP\myEnv\lib\site-packages\django\contrib\admin\options.py" in save_model
  1027.         obj.save()

File "C:\Users\HP\myEnv\lib\site-packages\django\contrib\auth\base_user.py" in save
  73.         super().save(*args, **kwargs)

File "C:\Users\HP\myEnv\lib\site-packages\django\db\models\base.py" in save
  729.                        force_update=force_update, update_fields=update_fields)

File "C:\Users\HP\myEnv\lib\site-packages\django\db\models\base.py" in save_base
  769.                 update_fields=update_fields, raw=raw, using=using,

File "C:\Users\HP\myEnv\lib\site-packages\django\dispatch\dispatcher.py" in send
  178.             for receiver in self._live_receivers(sender)

File "C:\Users\HP\myEnv\lib\site-packages\django\dispatch\dispatcher.py" in <listcomp>
  178.             for receiver in self._live_receivers(sender)

File "C:\Users\HP\My Documents\github\erpcloud\erpcloud\userprofile\models.py" in user_created_profilespecific
  99.       Profile.objects.create(Name=instance,image='userprofile/download (1).jpg')

File "C:\Users\HP\myEnv\lib\site-packages\django\db\models\manager.py" in manager_method
  82.                 return getattr(self.get_queryset(), name)(*args, **kwargs)

File "C:\Users\HP\myEnv\lib\site-packages\django\db\models\query.py" in create
  417.         obj.save(force_insert=True, using=self.db)

File "C:\Users\HP\My Documents\github\erpcloud\erpcloud\userprofile\models.py" in save
  84.           super(Profile, self).save(*args, **kwargs)

File "C:\Users\HP\myEnv\lib\site-packages\django\db\models\base.py" in save
  729.                        force_update=force_update, update_fields=update_fields)

File "C:\Users\HP\myEnv\lib\site-packages\django\db\models\base.py" in save_base
  754.                 update_fields=update_fields,

File "C:\Users\HP\myEnv\lib\site-packages\django\dispatch\dispatcher.py" in send
  178.             for receiver in self._live_receivers(sender)

File "C:\Users\HP\myEnv\lib\site-packages\django\dispatch\dispatcher.py" in <listcomp>
  178.             for receiver in self._live_receivers(sender)

File "C:\Users\HP\My Documents\github\erpcloud\erpcloud\userprofile\models.py" in product_activation
  105.  for product in instance.subscribed_products.all():

File "C:\Users\HP\myEnv\lib\site-packages\django\db\models\fields\related_descriptors.py" in __get__
  498.         return self.related_manager_cls(instance)

File "C:\Users\HP\myEnv\lib\site-packages\django\db\models\fields\related_descriptors.py" in __init__
  795.                                  (instance, self.pk_field_names[self.source_field_name]))

Exception Type: ValueError at /admin/auth/user/add/
Exception Value: "<Profile: surajkar>" needs to have a value for field "id" before this many-to-many relationship can be used.

如果有人知道该解决方案,请提供带有简短说明的正确代码,因为它将帮助我学习新知识。因为我是python和django的新手,所以。

谢谢

1 个答案:

答案 0 :(得分:3)

就像错误提示一样,您在保存配置文件之前尝试使用多对多关系。由于m2m关系实际上是一个单独的链接表中的一个条目,在关系的每一侧都存储了对象的ID,因此在该ID实际上存在之前,您不能使用它。即,保存后。

解决方案只是让您的信号监听post_save,而不是pre_save