【问题标题】:must be instance django必须是实例 django
【发布时间】:2019-03-21 07:32:13
【问题描述】:

这是商家模式:

class Merchant(models.Model):
     merchant_token = models.CharField(max_length=255, unique=True)

这是交易模型,第一个字段与 Merchant 模型上的 Merchant_token 相关联:

class Transaction(models.Model):
     transaction_merchant_token = models.ForeignKey(Merchant, on_delete=models.CASCADE)

首先我通过 POST 请求获取商家令牌,然后通过以下方式获取商家字段:

merchant = Merchant.objects.get(merchant_token__exact=posted_token)

但是当我想插入带有已发布令牌的新交易时:

new_transaction = Transaction(
                                transaction_merchant_token=merchant.merchant_token
                            )
                            new_transaction.save()

我得到 ValueError 异常:

无法分配“93C38:9VLlOUuaRq7J8boHyX80cI5MYy8yCpsb”:Transaction.transaction_merchant_token 必须是商家实例。

【问题讨论】:

    标签: django foreign-keys valueerror


    【解决方案1】:

    您应该传递商家实例本身而不是令牌

    new_transaction = Transaction(transaction_merchant_token=merchant)
    new_transaction.save()
    

    我会重新定义模型,使其看起来像这样

    class Merchant(models.Model):
         token = models.CharField(max_length=255, unique=True)
    
    class Transaction(models.Model):
         merchant = models.ForeignKey(Merchant, on_delete=models.CASCADE)
    

    那么当你想要获取商家令牌的时候,你就这样做

    new_transaction.merchant.token
    

    【讨论】:

      【解决方案2】:

      从概念上讲,ForeignKey 指的是一个模型对象,而不是该对象的主键。

      是的,Django 会创建一个field_id(假设ForeignKey 字段的名称是field)来存储被引用模型对象的主键值,并且只有field_id 是真实的数据库列。但是field_idfield 不同

      因此你可以做两件事:

      1. 您使用transaction_merchant_token 字段,并传递一个Merchant 对象:

        new_transaction = Transaction(
            transaction_merchant_token=merchant
        )
      2. 您使用transaction_merchant_token_id 字段,然后您传递主键的值(例如令牌):

        new_transaction = Transaction(
            transaction_merchant_token_id=merchant.pk
        )

      注意命名法):由于 ForeignKey 因此不是令牌本身,因此通常在模型之后命名 ForeignKey, 不在模型对象的主键之后,所以我建议重命名 您的外键,例如:

      class Transaction(models.Model):
           transaction_merchant = models.ForeignKey(Merchant, on_delete=models.CASCADE)

      甚至更好:

      class Transaction(models.Model):
           merchant = models.ForeignKey(Merchant, on_delete=models.CASCADE)

      在属性前面加上当前模型的名字不是 必要的,如果你想在 功能。

      【讨论】:

      • 这个解释再好不过了!我想补充一点,如果他要接受第二个建议,他必须通过将unique=True 替换为primary_key=True 来更新merchant_token 字段。
      • @NourChawich: aarrghhh... 是的,我以某种方式误读了它,感谢您的提醒。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-03-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-16
      • 2016-07-25
      相关资源
      最近更新 更多