[英]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.