SlugRelatedField自动创建关联表对象
例如有以下模型类,此处外键设置时blank和null约束条件必须设为True
class Book(models.Model):
book_id = models.CharField(max_length=150)
name = models.CharField(max_length=50)
class Meta:
db_table = 'book'
class Characters(models.Model):
name = models.CharField(max_length=50)
books =models.ForeignKey('Book',related_name='Characters',on_delete=models.CASCADE,blank=True,null=True)
class Meta:
db_table = 'characters'
DRF中利用SlugRelatedField字段进行反序列化时,假如想同时反序列化数据到关联表,可以重写 SlugRelatedFiedld类里的to_internal_value方法。前提:slug_field指定字段是唯一必传字段,先看看 to_internal_value代码。
class SlugRelatedField(RelatedField):
"""
A read-write field that represents the target of the relationship
by a unique 'slug' attribute.
以唯一字段表示表之间关系
"""
.......
def to_internal_value(self, data):
try:
return self.get_queryset().get(**{self.slug_field: data}) # 获取返回slug_field指定字段所传入的数据。
except ObjectDoesNotExist:
self.fail('does_not_exist', slug_name=self.slug_field, value=smart_str(data))
except (TypeError, ValueError):
self.fail('invalid')
.......
此处把self.get_queryset().get({self.slug_field: data})重写为get_or_create({self.slug_field: data})[0]即可。
# 重写to_internal_value方法
class SlugRelatedField(serializers.SlugRelatedField):
def to_internal_value(self, data):
try:
return self.get_queryset().get_or_create(**{self.slug_field: data})[0]
except (TypeError, ValueError):
self.fail('invalid')
# 定义书本序列化器
class BookSerializers(serializers.ModelSerializer):
Characters=SlugRelatedField(many=True,queryset=Characters.objects.all(),slug_field='name')
class Meta:
model = Book
fields = ['book_id','name','Characters']
传入数据校验并保存到数据库
data = {
"book_id":1,
"name":"神雕侠侣",
"Characters":["杨过","小龙女","郭靖"]
}
bs = BookSerializers(data=data)
bs.is_valid()
bs.save()
结果如下图