如何使用事务为嵌套关系创建序列化程序,其中嵌套关系具有多个子类型?我已经通读了文档,似乎没有很好地涵盖。
我们有一个投保房主的应用程序,具有以下结构:
class Homeowner(models.Model):
name = models.CharField(max_length = 100, null = True, blank = True)
property = models.ForeignKey(Property, null = True)
class Property(models.Model):
address = models.CharField(max_length = 500, null = True, blank = True)
# lots more removed. Not an abstract model.
class House(Property):
number_of_floors = models.IntegerField(default = 1)
class Condo(Property):
has_doorman = models.BooleanField(default = False)
字符串
(This严格地说是作秀;不同的房屋类型有很多折扣或负债字段。)多年来,我们的方法是手工输入房产,然后将房主作为两个独立的阶段输入,并将它们与房主页面上的房产搜索对话框链接起来。一直都是零或一对一的关系:一个房产可能有零个或一个房主,一个房主可能有零个或一个房产。
订单已经下来,以创建一个统一的体验,房主可以自己填写:输入所有内容,房主和财产,并一起验证它们,如果有任何失败,则回滚所有内容。可悲的是,太多的依赖于现有的结构来重新安排模型。据我所知(我已经和Django搏斗了好几年了),如果我只是有一个属性,它会像这样简单:
class PolicySerializer(serializers.ModelSerializer):
property = PropertySerializer()
class Meta:
model = Homeowner
fields = ['name', 'property']
def create(self, validated_data):
property_data = validated_data.pop('property')
property = Property.objects.create(**property_data)
Homeowner.objects.create(property=property, **validated_data)
return homeowner
型
检测房主填写了什么类型的属性表单是相当简单的,但是一旦我知道了,我如何编写create()
方法来路由到正确类型的属性子类型模型?
如果Homeowner对象验证失败,如何确保Property对象不会被闲置?这是自动处理的吗?还是应该用@transaction.atomic
修饰create()
方法?
1条答案
按热度按时间jhiyze9q1#
您应该为每个属性子类型(House和Condo)定义序列化程序,然后为属性模型创建序列化程序,该序列化程序将根据输入数据动态确定子类型,最后您应该创建Homeowner序列化程序,包括属性序列化程序。
你的属性序列化器应该是这样的:
字符串
现在我们可以创建属性序列化器来处理不同的sybtypes:
型
最后是HomeOwner序列化器:
型
你应该使用
@transaction.atomic
decorator来确保如果创建过程的任何部分失败,整个事务将被回滚。您可能存在一些验证错误(views.py),需要处理
您可以通过使用模型继承和序列化程序来自动处理子类型,使其更具动态性和可伸缩性。
我们可以像这样使用模型继承:
型
现在我们可以使用序列化器来处理不同的子类型:
型
现在你不需要手动更新每个子类型的if子句,相反,序列化器会根据数据中提供的
type
字段自动检测子类型,序列化器会根据检测到的子类型处理其余的子类型。注意,你应该给传入的数据分配一个
type
字段来确定子类型。请记住,在向API发送数据时要包含
type
字段,以便序列化程序可以正确识别子类型,如下所示:型
我希望这对你有帮助。