首页 > 解决方案 > 必须是实例 django

问题描述

这是商家模型:

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 必须是商家实例。

标签: djangoforeign-keysvalueerror

解决方案


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

是的,Django 将创建一个field_id(给定ForeignKey字段的名称field)来存储引用模型对象的主键的值,并且只有field_id是一个真正的数据库列。但是field_id,a 不同field

因此,您可以做两件事:

  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)

没有必要在属性前面加上当前模型的名称,如果你想在函数中使用“ duck typing ”可能会很糟糕。


推荐阅读