首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Django - DRF验证

Django - DRF验证
EN

Stack Overflow用户
提问于 2018-07-03 10:42:54
回答 2查看 509关注 0票数 0

我正在设计一个API,它将由不同的合作伙伴使用。以下是API虚拟有效载荷:

代码语言:javascript
复制
{
    key1: value1,
    key2: value2,
    key3: value3,
    key4: value4,
    key5: value5,
    partner: partner_code
}

现在,我有了一个模型,在这个模型中需要保存上面的字段。

代码语言:javascript
复制
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)

另外,我有一个序列化程序:-

代码语言:javascript
复制
class TableSerializer(models.Model):
    class Meta:
        model = Table
        fields = '__all__'

现在,每当数据是POSTed时,我就序列化(和验证)数据,然后保存它。我就是这样做的。

代码语言:javascript
复制
serializer = TableSerializer(data=payload)
if serializer.is_valid():
    serializer.save()

这是正常的DRF流。现在,出现的问题是,我需要将自定义验证wrt应用到每个合作伙伴。例如:-

代码语言:javascript
复制
`key2` and `key4` are mandatory for PartnerA. Similarly, for PartnerB, max value of `key1` is 100 and many more.

根据当前的DRF流,我需要在序列化程序中添加if-else条件。

代码语言:javascript
复制
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序列化程序?

EN

回答 2

Stack Overflow用户

发布于 2018-07-03 11:11:22

您可以使用合作伙伴== partnerB或类似的方法编写更多的序列化器(此序列化程序仅用于验证),并执行以下操作:

代码语言:javascript
复制
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

我认为这个决定不是很好,但是您可以尝试,或者您可以编写自定义验证器并使用它进行验证。

票数 0
EN

Stack Overflow用户

发布于 2019-01-26 14:23:17

我建议只使用基本验证和合作伙伴id/name/type/etc之间的映射将基本序列化程序设置为特定的序列化程序:

代码语言:javascript
复制
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 = TableSerializer
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51152558

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档