簡體   English   中英

Django Rest Framework序列化程序驗證器始終為空

[英]Django Rest Framework serializer validator always empty

我正在嘗試打印django rest框架中的驗證器列表,但是當我打印出來時,它似乎總是空的。

這是代碼的一部分

class AccountViewSet(viewsets.ModelViewSet):
    lookup_field = 'username'
    queryset = Account.objects.all()
    serializer_class = AccountSerializer


    def create(self, request):

        serializer = self.serializer_class(data=request.data)
        # this always return []
        print serializer.validators

這是違反直覺的,因為當我在request.data測試無效數據時,該代碼顯然會運行驗證程序,因為is_valid()返回錯誤(如文檔所示)。 因此,我可以觀察到驗證器生效但無法打印出來是沒有意義的。 有人可以指出我所缺少的嗎?

謝謝

為什么您的情況下serializer.validators返回[]

發生這種情況的原因是,在創建序列化程序的實例時,尚未將validators參數傳遞給序列化程序。 如果您傳遞了validators參數,則將serializer._validators設置為該值。 然后,如果您檢查serializer.validators ,它將為您提供通過的驗證器列表。

例如:

In [1]: serializer = SomeSerializer(data=some_data, validators=[validator1, validator2])

In [2]: serializer.validators
Out [2]: [validator1, validator2] # gives the list of validators

默認情況下,如果在訪問serializer.validators時未傳遞任何驗證器,則返回[]

供參考的源代碼:

現在, BaseSerializer繼承自Field類,該類調用其__init__()

class BaseSerializer(Field):

    def __init__(self, instance=None, data=empty, **kwargs):
        ...
        super(BaseSerializer, self).__init__(**kwargs)

在這里, default_validators是一個空列表[]

class Field(object):

    default_validators = [] # an empty list by default
    default_empty_html = empty
    initial = None

    def __init__(self, read_only=False, write_only=False,
                 required=None, default=empty, initial=empty, source=None,
                 label=None, help_text=None, style=None,
                 error_messages=None, validators=None, allow_null=False):

        ...

        # Here, it checks if validators argument was passed when creating the serializer instance
        # If you have passed, then `.validators` will be set to that value.
        if validators is not None:
            self.validators = validators[:]

        ...

    @property
    def validators(self):
        if not hasattr(self, '_validators'): 
            # This will be executed as there was no validators passed in kwargs
            self._validators = self.get_validators()
        return self._validators

    @validators.setter
    def validators(self, validators):
        self._validators = validators


    def get_validators(self):
        return self.default_validators[:] # returns empty list

為什么您的代碼顯示無效數據錯誤呢?

這是因為字段級驗證程序導致了該錯誤。 您的序列化程序級別的驗證程序是[]但是有些字段級別的驗證程序正在引發無效數據錯誤。

要查看字段級驗證器,可以執行print repr(serializer)

http://www.django-rest-framework.org/api-guide/validators/

REST框架中的驗證

Django REST框架序列化程序中的驗證與Django的ModelForm類中的驗證工作方式稍有不同。

使用ModelForm,驗證部分在表單上執行,部分在模型實例上執行。 使用REST框架,驗證完全在序列化程序類上執行。 由於以下原因,這是有利的:

  • 它引入了適當的關注點分離,使您的代碼行為更加明顯。
  • 在使用快捷方式ModelSerializer類和使用顯式Serializer類之間進行切換很容易。 用於ModelSerializer的任何驗證行為都易於復制。
  • 打印序列化程序實例的repr將准確顯示其適用的驗證規則。 在模型實例上沒有調用任何額外的隱藏驗證行為。

使用ModelSerializer時,所有這些都會自動為您處理。 如果要改為使用Serializer類,則需要顯式定義驗證規則。

作為REST框架如何使用顯式驗證的示例,我們將使用一個簡單的模型類,該類具有一個具有唯一性約束的字段。

 class CustomerReportRecord(models.Model): time_raised = models.DateTimeField(default=timezone.now, editable=False) reference = models.CharField(unique=True, max_length=20) description = models.TextField() 

這是一個基本的ModelSerializer,可用於創建或更新CustomerReportRecord實例:

 class CustomerReportSerializer(serializers.ModelSerializer): class Meta: model = CustomerReportRecord 

如果我們使用manage.py shell打開Django shell,我們現在可以

 >>> from project.example.serializers import CustomerReportSerializer >>> serializer = CustomerReportSerializer() >>> print(repr(serializer)) CustomerReportSerializer(): id = IntegerField(label='ID', read_only=True) time_raised = DateTimeField(read_only=True) reference = CharField(max_length=20, validators=[<UniqueValidator(queryset=CustomerReportRecord.objects.all())>]) description = CharField(style={'type': 'textarea'}) 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM