serializer.is_valid() 适用于整数字段,但 serializer.save() 要求模型实例
serializer.is_valid() works with integer fields but serializer.save() asks for model instance
我在ma数据库中有一个多对多的关系(PK是整数)。我从数据库自动生成 django 模型并实现了最简单的序列化程序。
当我将带有整数的字典提供给序列化程序时,serializer.is_valid() returns 正确,但是 serializer.save() 表示字段应该是模型实例。
但是当我给出一个包含模型实例的字典时,serializer.is_valid() returns False.
data = {'tag_id': 9, 'spending_id': 17}
serializer = TagspendingSerializer(data= data)
serializer.is_valid()
True
serializer.save()
=> ValueError:无法分配“9”:"Tagspending.tag_id" 必须是 "Tag" 实例。
data = {'tag_id': Tag.objects.get(tag_id= 9), 'spending_id': Spending.objects.get(spending_id= 17)}
serializer = TagspendingSerializer(data= data)
serializer.is_valid()
=> 错误
这是我的模型:
class Tagspending(models.Model):
tag_id = models.ForeignKey(Tag, models.DO_NOTHING, db_column='tag_ID', primary_key=True)
spending_id = models.ForeignKey(Spending, models.DO_NOTHING, db_column='spending_ID')
class Meta:
managed = True
db_table = 'TagSpending'
unique_together = (('tag_id', 'spending_id'),)
这是我的序列化程序:
class TagspendingSerializer(serializers.ModelSerializer):
class Meta:
model = Tagspending
fields = ('tag_id', 'spending_id')
由于您使用 tag_id
作为主键,因此 Django Rest Framework
似乎存在错误。
你应该改变你的模型,这是最好的做法,通过改变与 Tag
的关系作为 OneToOneField
(因为它是一个主键,这种关系是唯一的,因此 OneToOneField
更配件)。你的序列化器应该可以工作了。
您还应该考虑重命名您的模型字段。无需引入 '_id' 后缀。
我想有些东西可以让你更清楚一点
Django 这样做:
ForeignKey defines an extra attribute with _id appended to the field name
您的模型中有以下字段:
tag_id = models.ForeignKey(Tag, models.DO_NOTHING, db_column='tag_ID', primary_key=True)
但您实际上并不需要指定数据库列或主键,而是这样做:
tag = models.ForeignKey(Tag, models.DO_NOTHING)
在 db 中,该字段的 db 列的名称为 tag_id(如您所愿),类型为整数。
这就是验证通过的原因。
现在,您可以访问 ID instance.tag_id
或 instance.tag.id
(但是这两个调用之间存在差异 - 如果尚未检索到,则访问数据库)。
但是,在您的情况下 'tag_id' 是 ForeignKey 并且需要 "Tag" 个实例。
您有 2 种可能的方法来解决此问题(假设您使用我建议的更改来重命名该字段)
1) 您可以在 post 请求中使用 tag_id(现在,将字段名称更改为 tag
)
2) 在你的序列化器中,你可以指定以下内容:
tag = serializers.PrimaryKeyRelatedField(queryset=Tag.objects.all())
你可以用
做 post 请求
{"tag" : 1 }
这会将您的 ID 解析为 Tag 实例(如果有效)
我在ma数据库中有一个多对多的关系(PK是整数)。我从数据库自动生成 django 模型并实现了最简单的序列化程序。
当我将带有整数的字典提供给序列化程序时,serializer.is_valid() returns 正确,但是 serializer.save() 表示字段应该是模型实例。
但是当我给出一个包含模型实例的字典时,serializer.is_valid() returns False.
data = {'tag_id': 9, 'spending_id': 17}
serializer = TagspendingSerializer(data= data)
serializer.is_valid()
True
serializer.save()
=> ValueError:无法分配“9”:"Tagspending.tag_id" 必须是 "Tag" 实例。
data = {'tag_id': Tag.objects.get(tag_id= 9), 'spending_id': Spending.objects.get(spending_id= 17)}
serializer = TagspendingSerializer(data= data)
serializer.is_valid()
=> 错误
这是我的模型:
class Tagspending(models.Model):
tag_id = models.ForeignKey(Tag, models.DO_NOTHING, db_column='tag_ID', primary_key=True)
spending_id = models.ForeignKey(Spending, models.DO_NOTHING, db_column='spending_ID')
class Meta:
managed = True
db_table = 'TagSpending'
unique_together = (('tag_id', 'spending_id'),)
这是我的序列化程序:
class TagspendingSerializer(serializers.ModelSerializer):
class Meta:
model = Tagspending
fields = ('tag_id', 'spending_id')
由于您使用 tag_id
作为主键,因此 Django Rest Framework
似乎存在错误。
你应该改变你的模型,这是最好的做法,通过改变与 Tag
的关系作为 OneToOneField
(因为它是一个主键,这种关系是唯一的,因此 OneToOneField
更配件)。你的序列化器应该可以工作了。
您还应该考虑重命名您的模型字段。无需引入 '_id' 后缀。
我想有些东西可以让你更清楚一点
Django 这样做:
ForeignKey defines an extra attribute with _id appended to the field name
您的模型中有以下字段:
tag_id = models.ForeignKey(Tag, models.DO_NOTHING, db_column='tag_ID', primary_key=True)
但您实际上并不需要指定数据库列或主键,而是这样做:
tag = models.ForeignKey(Tag, models.DO_NOTHING)
在 db 中,该字段的 db 列的名称为 tag_id(如您所愿),类型为整数。 这就是验证通过的原因。
现在,您可以访问 ID instance.tag_id
或 instance.tag.id
(但是这两个调用之间存在差异 - 如果尚未检索到,则访问数据库)。
但是,在您的情况下 'tag_id' 是 ForeignKey 并且需要 "Tag" 个实例。
您有 2 种可能的方法来解决此问题(假设您使用我建议的更改来重命名该字段)
1) 您可以在 post 请求中使用 tag_id(现在,将字段名称更改为 tag
)
2) 在你的序列化器中,你可以指定以下内容:
tag = serializers.PrimaryKeyRelatedField(queryset=Tag.objects.all())
你可以用
做 post 请求{"tag" : 1 }
这会将您的 ID 解析为 Tag 实例(如果有效)