我在ma数据库中有多对多关系(PK是整数)。我从数据库自动生成了django模型,并实现了最简单的序列化器。
当我给序列化器提供一个包含整数的字典时,serializer.is_valid()返回True,但是serializer.save()表示字段应该是模型实例。
但是当我给字典提供模型实例时,serializer.is_valid()返回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')
答案 0 :(得分:1)
我认为有些事情需要您澄清
Django这样做:
ForeignKey定义了一个额外的属性,在字段名称后附加了_id
您的模型中包含以下字段:
tag_id = models.ForeignKey(Tag, models.DO_NOTHING, db_column='tag_ID', primary_key=True)
但是您实际上并不需要指定db列或主键,而是这样做:
tag = models.ForeignKey(Tag, models.DO_NOTHING)
在db中,此字段的db列将具有名称tag_id(如您所愿),并且类型将为整数。 这就是验证通过的原因。
现在,您可以访问ID instance.tag_id
或instance.tag.id
(但是,这两个调用之间是有区别的-如果尚未检索,则会命中数据库)。
但是,在您的情况下,'tag_id'是ForeignKey并需要“ Tag”实例。
您有2种可能的方法来解决此问题(假设您使用我建议的更改来重命名该字段)
1)您可以在帖子请求中使用tag_id(现在,将字段更改名称更改为tag
)
2)在序列化程序中,您可以指定以下内容:
tag = serializers.PrimaryKeyRelatedField(queryset=Tag.objects.all())
,您可以使用
进行发布请求{"tag" : 1 }
,这会将您的ID解析为Tag实例(如果有效)
答案 1 :(得分:0)
由于您使用Django Rest Framework
作为主键,因此tag_id
似乎存在一个错误。
您应该通过将Tag
更改为OneToOneField
来更改模型,这是最佳实践(因为它是主键,所以这种关系是唯一的,因此OneToOneField
更配件)。然后,您的序列化程序应该可以工作。
您还应该考虑重命名模型字段。无需引入“ _id”后缀。