如何在DRF序列化器中为新建Django模型实例添加Taggit标签?
在DRF序列化器中为新建Django模型实例添加Taggit标签时出现
list object has no attribute add错误 尝试在DRF序列化器中为新建的Django模型实例添加Taggit标签时,程序抛出错误:list object has no attribute add。目前仅能通过从数据库重新获取实例的方式临时解决,但这种方法不够优雅,且调用模型的refresh_from_db方法无法解决问题。
相关代码示例
class ThingSerializer(serializers.ModelSerializer): def create(self, validated_data): # 执行报错:`list object has no attribute add` thing = Thing.objects.create(**validated_data) custom_tags = validated_data.pop("custom_tags", []) for custom_tag in custom_tags: thing.custom_tags.add( custom_tag.pop("name"), tag_kwargs=custom_tag ) thing.save() def create_with_hack(self, validated_data): # 从数据库重新获取实例后可正常执行 thing = Thing.objects.create(**validated_data) thing_ = Thing.objects.get(pk=thing.id) custom_tags = validated_data.pop("custom_tags", []) for custom_tag in custom_tags: thing_.custom_tags.add( custom_tag.pop("name"), tag_kwargs=custom_tag ) thing_.save()
环境信息
- Python 3.8
- Django 4.2.2
- Taggit 4.0.0
问题原因
报错核心原因:调用Thing.objects.create(**validated_data)时,validated_data中包含的custom_tags(列表类型)会直接赋值给模型实例的custom_tags属性,覆盖了Taggit提供的TaggableManager对象。此时thing.custom_tags变成普通列表,自然没有add方法。
解决方案
在创建模型实例前,先将custom_tags从validated_data中弹出,避免它被传入create方法覆盖TaggableManager:
class ThingSerializer(serializers.ModelSerializer): def create(self, validated_data): # 先移除custom_tags,不传入create方法 custom_tags = validated_data.pop("custom_tags", []) thing = Thing.objects.create(**validated_data) # 此时thing.custom_tags仍是TaggableManager,可正常调用add for custom_tag in custom_tags: thing.custom_tags.add( custom_tag.pop("name"), tag_kwargs=custom_tag ) return thing
注:调用
TaggableManager.add()方法后会自动保存关联关系,无需额外调用thing.save()。
内容的提问来源于stack exchange,提问作者pdoherty926
相关产品推荐
相关产品推荐

