我正在设计一个API,它将由不同的合作伙伴使用。以下是API虚拟有效载荷:
{
key1: value1,
key2: value2,
key3: value3,
key4: value4,
key5: value5,
partner: partner_code
}现在,我有了一个模型,在这个模型中需要保存上面的字段。
class Table(models.Model):
key1 = models.IntegerField()
key2 = models.IntegerField(blank=True, null=True)
key3 = models.IntegerField()
key4 = models.IntegerField(blank=True, null=True)
key5 = models.CharField(max_length=255)
partner = models.ForeignKey(Partner)另外,我有一个序列化程序:-
class TableSerializer(models.Model):
class Meta:
model = Table
fields = '__all__'现在,每当数据是POSTed时,我就序列化(和验证)数据,然后保存它。我就是这样做的。
serializer = TableSerializer(data=payload)
if serializer.is_valid():
serializer.save()这是正常的DRF流。现在,出现的问题是,我需要将自定义验证wrt应用到每个合作伙伴。例如:-
`key2` and `key4` are mandatory for PartnerA. Similarly, for PartnerB, max value of `key1` is 100 and many more.根据当前的DRF流,我需要在序列化程序中添加if-else条件。
class TableSerializer(models.Model):
def validate(self, data):
if partner == `partnerA`:
# checkfor key1 max value.
# check the mandatory fields.
elif partner == `partnerB`:
# some custom validations
# and so on
class Meta:
model = Table
fields = '__all__'这个if-else可以继续增长,这是一个糟糕的设计。我如何引入另一个名为Validation Engine的组件,它可以首先验证数据,然后将经过验证的数据传递给DRF序列化程序?
发布于 2018-07-03 11:11:22
您可以使用合作伙伴== partnerB或类似的方法编写更多的序列化器(此序列化程序仅用于验证),并执行以下操作:
def validate(self, data):
data_is_valid = False
for serializer_class in selializers_for_validate:
serializer = serializer_class(data=data)
is_valid = serializer.is_valid()
if is_valid:
break
if not is_valid:
raise serializers.ValidationError(<here your custom error>)
return data我认为这个决定不是很好,但是您可以尝试,或者您可以编写自定义验证器并使用它进行验证。
发布于 2019-01-26 14:23:17
我建议只使用基本验证和合作伙伴id/name/type/etc之间的映射将基本序列化程序设置为特定的序列化程序:
from django.db import models
from rest_framework import serializers
from rest_framework.viewsets import ModelViewSet
# models.py
class Table(models.Model):
key1 = models.IntegerField()
key2 = models.IntegerField(blank=True, null=True)
key3 = models.IntegerField()
key4 = models.IntegerField(blank=True, null=True)
key5 = models.CharField(max_length=255)
partner = models.ForeignKey(Partner)
# serializers.py
class TableSerializer(serializers.ModelSerializer):
partner_serializers = {}
class Meta:
model = Table
fields = '__all__'
def validate(self, data):
self.partner_serializers[data['partner']['partner_id']](
instance=self.instance,
data=data
).is_valid(raise_exception=True)
return super().validate(data)
@classmethod
def register_partner_validator(cls, partner_id):
def wrapped(serializer):
cls.partner_serializers[partner_id] = serializer
return serializer
return wrapped
@TableSerializer.register_partner_validator('thePartner1')
class Partner1TableSerializer(TableSerializer):
class Meta:
extra_kwargs = {
'key3': {'max_value': 3}
}
def validate(self, data):
if data['key1'] + data['key2'] > 5:
raise serializers.ValidationError('Wrong!')
@TableSerializer.register_partner_validator('thePartner2')
class Partner2TableSerializer(TableSerializer):
def validate(self, data):
if data['key1'] + data['key5'] < 5:
raise serializers.ValidationError('Wrong!')
# views.py
class TableViewSet(ModelViewSet):
queryset = Table.objects.all()
serializer_class = TableSerializerhttps://stackoverflow.com/questions/51152558
复制相似问题