Django 序列化程序:为什么 self.fields.pop('field_name') 有效?
Django serializers: why does self.fields.pop('field_name') work?
参考以下 link 作为示例(其他地方还有很多其他示例):
http://www.django-rest-framework.org/api-guide/serializers/#dynamically-modifying-fields
据了解,Django 序列化程序字段通常使用不可变的元组定义:
class UserSerializer(DynamicFieldsModelSerializer):
class Meta:
model = User
fields = ('id', 'username', 'email')
但是,动态更改序列化程序字段的公认方法涉及使用弹出 (self.fields.pop(field_name)
)
class DynamicFieldsModelSerializer(serializers.ModelSerializer):
def __init__(self, *args, **kwargs):
# Don't pass the 'fields' arg up to the superclass
fields = kwargs.pop('fields', None)
# Instantiate the superclass normally
super(DynamicFieldsModelSerializer, self).__init__(*args, **kwargs)
if fields is not None:
# Drop any fields that are not specified in the `fields` argument.
allowed = set(fields)
existing = set(self.fields)
for field_name in existing - allowed:
self.fields.pop(field_name)
如何定义字段? Django 序列化程序中是否有预处理步骤?
您可以覆盖序列化程序 init 方法并根据查询参数动态设置字段属性。您可以通过传递给序列化程序的上下文访问请求对象。
我在这里创建了一个可重用的 mixin,用于修改动态字段。
从 rest_framework 导入序列化程序
class DynamicFieldsModelSerializer(serializers.ModelSerializer):
"""
一个带有额外 fields
参数的 ModelSerializer
控制应显示哪些字段。
"""
def __init__(self, *args, **kwargs):
# Instantiate the superclass normally
super(DynamicFieldsModelSerializer, self).__init__(*args, **kwargs)
fields = self.context['request'].QUERY_PARAMS.get('fields')
if fields:
fields = fields.split(',')
# Drop any fields that are not specified in the `fields` argument.
allowed = set(fields)
existing = set(self.fields.keys())
for field_name in existing - allowed:
self.fields.pop(field_name)
class UserSerializer(DynamicFieldsModelSerializer):
class Meta:
model = User
fields = ('id', 'username', 'email')
查看:
def fields(self):
"""
A dictionary of {field_name: field_instance}.
"""
# `fields` is evaluated lazily. We do this to ensure that we don't
# have issues importing modules that use ModelSerializers as fields,
# even if Django's app-loading stage has not yet run.
if not hasattr(self, '_fields'):
self._fields = BindingDict(self)
for key, value in self.get_fields().items():
self._fields[key] = value
return self._fields
How do fields get defined?
现在应该清楚了。
Is there a pre-processing step in Django serializers?
是的。
这个"step"叫做metaclass
并且Serializer
s、Model
s、Forms
是元类。
参考以下 link 作为示例(其他地方还有很多其他示例): http://www.django-rest-framework.org/api-guide/serializers/#dynamically-modifying-fields
据了解,Django 序列化程序字段通常使用不可变的元组定义:
class UserSerializer(DynamicFieldsModelSerializer):
class Meta:
model = User
fields = ('id', 'username', 'email')
但是,动态更改序列化程序字段的公认方法涉及使用弹出 (self.fields.pop(field_name)
)
class DynamicFieldsModelSerializer(serializers.ModelSerializer):
def __init__(self, *args, **kwargs):
# Don't pass the 'fields' arg up to the superclass
fields = kwargs.pop('fields', None)
# Instantiate the superclass normally
super(DynamicFieldsModelSerializer, self).__init__(*args, **kwargs)
if fields is not None:
# Drop any fields that are not specified in the `fields` argument.
allowed = set(fields)
existing = set(self.fields)
for field_name in existing - allowed:
self.fields.pop(field_name)
如何定义字段? Django 序列化程序中是否有预处理步骤?
您可以覆盖序列化程序 init 方法并根据查询参数动态设置字段属性。您可以通过传递给序列化程序的上下文访问请求对象。
我在这里创建了一个可重用的 mixin,用于修改动态字段。
从 rest_framework 导入序列化程序
class DynamicFieldsModelSerializer(serializers.ModelSerializer):
"""
一个带有额外 fields
参数的 ModelSerializer
控制应显示哪些字段。
"""
def __init__(self, *args, **kwargs):
# Instantiate the superclass normally
super(DynamicFieldsModelSerializer, self).__init__(*args, **kwargs)
fields = self.context['request'].QUERY_PARAMS.get('fields')
if fields:
fields = fields.split(',')
# Drop any fields that are not specified in the `fields` argument.
allowed = set(fields)
existing = set(self.fields.keys())
for field_name in existing - allowed:
self.fields.pop(field_name)
class UserSerializer(DynamicFieldsModelSerializer):
class Meta:
model = User
fields = ('id', 'username', 'email')
查看:
def fields(self):
"""
A dictionary of {field_name: field_instance}.
"""
# `fields` is evaluated lazily. We do this to ensure that we don't
# have issues importing modules that use ModelSerializers as fields,
# even if Django's app-loading stage has not yet run.
if not hasattr(self, '_fields'):
self._fields = BindingDict(self)
for key, value in self.get_fields().items():
self._fields[key] = value
return self._fields
How do fields get defined?
现在应该清楚了。
Is there a pre-processing step in Django serializers?
是的。 这个"step"叫做metaclass
并且Serializer
s、Model
s、Forms
是元类。