Django:序列化程序过滤掉未声明的字段
Django: Serializers filtering out undeclared fields
这是我的 MSV:
models.py
import mongoengine
class PersonAddressModel(mongoengine.DynamicEmbeddedDocument):
country = mongoengine.fields.StringField()
town = mongoengine.fields.StringField()
class PersonModel(mongoengine.DynamicDocument):
name = mongoengine.fields.StringField()
age = mongoengine.IntField()
is_married = mongoengine.fields.BooleanField()
address = EmbeddedDocumentListField(PersonAddressModel)
serializers.py
from rest_framework_mongoengine import serializers
from .models import PersonInfoModel, PersonAddressModel
import mongoengine
class PersonAddressSerializer(serializers.EmbeddedDocumentSerializer):
class Meta:
model = PersonAddressModel
fields = '__all__'
class PersonSerializer(serializers.DynamicDocumentSerializer):
class Meta:
model = PersonModel
fields = '__all__'
views.py
from rest_framework_mongoengine import viewsets
from .serializers import PersonSerializer, PersonAddressSerializer
from rest_framework.response import Response
from rest_framework import status
import djongo
from .models import PersonModel
class PersonView(viewsets.ModelViewSet):
lookup_field = 'id'
serializer_class = PersonSerializer
def create(self, request):
serializer = self.serializer_class(data=request.data)
try:
serializer.is_valid()
serializer.save()
except djongo.sql2mongo.SQLDecodeError:
return Response(
status=status.HTTP_503_SERVICE_UNAVAILABLE
)
return Response(
status=status.HTTP_201_CREATED
)
我要发送以下 json 对象:
{
"name": "Helmut",
"age": 21,
"is_married": true,
"address": [{"country": "Germany", "town": "Berlin", "street": "Wolfstraße 1"}]
}
然而,当我检查数据库时,我看到以下对象:
{
"_id" : ObjectId("5b5e201c540d1c3b7a4491e8"),
"name" : "Helmut",
"age" : 21,
"is_married" : true,
"address" : [
{
"country" : "Germany",
"town" : "Berlin"
}
]
}
也就是说,Helmut的街道不见了。我想知道为什么!我敢打赌它与序列化程序有关,但我无法弄清楚它到底是什么。
编辑
我希望我的两个文档都是动态的,因为某些 json 可能包含名称和值不可预测的字段,我也必须保存它们,所以我将两个模型 类 设为动态.但是我可以扩展 PersonInfoModel
但不能对 PersonAddressModel
做同样的事情。 street
字段不会出现在数据库中 (MongoDB)。
另一方面,我希望地址列表中的某些字段是必需的。
在您的 PersonAddressModel
中,您只定义了两个字段,即 country
和 town
。这意味着,在 DB 中,您使用这两个字段定义了模式,street
不包括在内。
因此,更改您的模型以添加额外的字段,如
class PersonAddressModel(mongoengine.DynamicEmbeddedDocument):
country = mongoengine.fields.StringField()
town = mongoengine.fields.StringField()
<b>street = mongoengine.fields.StringField()</b>
更新
如果您的 address
字段是动态的并且它是一个类似字典的字段,那么使用 mongoengine.fields.DictField()
as,
import mongoengine
class PersonModel(mongoengine.DynamicDocument):
name = mongoengine.fields.StringField()
age = mongoengine.IntField()
is_married = mongoengine.fields.BooleanField()
<b>address = mongoengine.fields.DictField()</b>
更新 2
你可以在 PersonSerializer
中做一个 field level validation
作为,
from rest_framework_mongoengine import serializers
<b>from rest_framework import serializers as drf_serializer</b>
class PersonSerializer(serializers.DynamicDocumentSerializer):
<b>def validate_address(self, address):
required_fields = ['street', 'country']
if not all([True for field in required_fields if field in address]):
raise drf_serializer.ValidationError('some required fields are missing')
return address</b>
class Meta:
model = PersonModel
fields = '__all__'
由于 rest_framework_mongoengine
没有 ValidationError
class,我们使用 DRF's ValidationError class
UPDATE-3
为了引发验证错误,您必须将 True
传递给 .is_valid()
(reff doc - Raising an exception on invalid data) 方法,如
class PersonView(viewsets.ModelViewSet):
lookup_field = 'id'
serializer_class = PersonSerializer
def create(self, request):
serializer = self.serializer_class(data=request.data)
try:
<b>serializer.is_valid(True) # Change is here <<<<</b>
serializer.save()
except djongo.sql2mongo.SQLDecodeError:
return Response(
status=status.HTTP_503_SERVICE_UNAVAILABLE
)
return Response(
status=status.HTTP_201_CREATED
)
这是我的 MSV:
models.py
import mongoengine
class PersonAddressModel(mongoengine.DynamicEmbeddedDocument):
country = mongoengine.fields.StringField()
town = mongoengine.fields.StringField()
class PersonModel(mongoengine.DynamicDocument):
name = mongoengine.fields.StringField()
age = mongoengine.IntField()
is_married = mongoengine.fields.BooleanField()
address = EmbeddedDocumentListField(PersonAddressModel)
serializers.py
from rest_framework_mongoengine import serializers
from .models import PersonInfoModel, PersonAddressModel
import mongoengine
class PersonAddressSerializer(serializers.EmbeddedDocumentSerializer):
class Meta:
model = PersonAddressModel
fields = '__all__'
class PersonSerializer(serializers.DynamicDocumentSerializer):
class Meta:
model = PersonModel
fields = '__all__'
views.py
from rest_framework_mongoengine import viewsets
from .serializers import PersonSerializer, PersonAddressSerializer
from rest_framework.response import Response
from rest_framework import status
import djongo
from .models import PersonModel
class PersonView(viewsets.ModelViewSet):
lookup_field = 'id'
serializer_class = PersonSerializer
def create(self, request):
serializer = self.serializer_class(data=request.data)
try:
serializer.is_valid()
serializer.save()
except djongo.sql2mongo.SQLDecodeError:
return Response(
status=status.HTTP_503_SERVICE_UNAVAILABLE
)
return Response(
status=status.HTTP_201_CREATED
)
我要发送以下 json 对象:
{
"name": "Helmut",
"age": 21,
"is_married": true,
"address": [{"country": "Germany", "town": "Berlin", "street": "Wolfstraße 1"}]
}
然而,当我检查数据库时,我看到以下对象:
{
"_id" : ObjectId("5b5e201c540d1c3b7a4491e8"),
"name" : "Helmut",
"age" : 21,
"is_married" : true,
"address" : [
{
"country" : "Germany",
"town" : "Berlin"
}
]
}
也就是说,Helmut的街道不见了。我想知道为什么!我敢打赌它与序列化程序有关,但我无法弄清楚它到底是什么。
编辑
我希望我的两个文档都是动态的,因为某些 json 可能包含名称和值不可预测的字段,我也必须保存它们,所以我将两个模型 类 设为动态.但是我可以扩展 PersonInfoModel
但不能对 PersonAddressModel
做同样的事情。 street
字段不会出现在数据库中 (MongoDB)。
另一方面,我希望地址列表中的某些字段是必需的。
在您的 PersonAddressModel
中,您只定义了两个字段,即 country
和 town
。这意味着,在 DB 中,您使用这两个字段定义了模式,street
不包括在内。
因此,更改您的模型以添加额外的字段,如
class PersonAddressModel(mongoengine.DynamicEmbeddedDocument):
country = mongoengine.fields.StringField()
town = mongoengine.fields.StringField()
<b>street = mongoengine.fields.StringField()</b>
更新
如果您的 address
字段是动态的并且它是一个类似字典的字段,那么使用 mongoengine.fields.DictField()
as,
import mongoengine
class PersonModel(mongoengine.DynamicDocument):
name = mongoengine.fields.StringField()
age = mongoengine.IntField()
is_married = mongoengine.fields.BooleanField()
<b>address = mongoengine.fields.DictField()</b>
更新 2
你可以在 PersonSerializer
中做一个 field level validation
作为,
from rest_framework_mongoengine import serializers
<b>from rest_framework import serializers as drf_serializer</b>
class PersonSerializer(serializers.DynamicDocumentSerializer):
<b>def validate_address(self, address):
required_fields = ['street', 'country']
if not all([True for field in required_fields if field in address]):
raise drf_serializer.ValidationError('some required fields are missing')
return address</b>
class Meta:
model = PersonModel
fields = '__all__'
由于 rest_framework_mongoengine
没有 ValidationError
class,我们使用 DRF's ValidationError class
UPDATE-3
为了引发验证错误,您必须将 True
传递给 .is_valid()
(reff doc - Raising an exception on invalid data) 方法,如
class PersonView(viewsets.ModelViewSet):
lookup_field = 'id'
serializer_class = PersonSerializer
def create(self, request):
serializer = self.serializer_class(data=request.data)
try:
<b>serializer.is_valid(True) # Change is here <<<<</b>
serializer.save()
except djongo.sql2mongo.SQLDecodeError:
return Response(
status=status.HTTP_503_SERVICE_UNAVAILABLE
)
return Response(
status=status.HTTP_201_CREATED
)