代码之家  ›  专栏  ›  技术社区  ›  Niladry Kar

ValueError:需要有字段“id”的值才能使用此多对多关系

  •  -1
  • Niladry Kar  · 技术社区  · 7 年前

    我创建了一个数字产品的电子商务应用程序,在这个应用程序中,我在产品模型的概要模型中创建了许多关系。

    在我添加了“多对多”字段之后,在我的配置文件模型中,它阻碍了我创建新的配置文件,并给出以下错误消息:

    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
    

    我已经在我的视图中完成了这项工作。

    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.
    

    如果有人知道解决方案,请提供适当的代码和简短的描述,因为它将帮助我学习新的东西。因为我是巨蟒和姜戈的新手。

    谢谢你

    1 回复  |  直到 7 年前
        1
  •  2
  •   Daniel Roseman    7 年前

    正如错误所说,在保存配置文件之前,您正在尝试使用多对多关系。由于M2M关系实际上是一个单独链接表中的一个条目,它将对象的ID存储在关系的每一侧,因此在该ID实际存在之前,您不能使用它;即,在保存之后。

    解决办法就是让你的信号听 post_save 不是 pre_save .