使用 Meta 和查询参数中的默认字段创建 Django Serializer
Create Django Serializer with default fields in Meta and query params
我正在尝试编写一个序列化程序,它将采用动态字段并将它们添加到 Meta
中指定的限制数量的字段中,但似乎没有方法可以将字段“添加回”创建后的序列化程序。
的动态字段
class DynamicFieldsModelSerializer(ModelSerializer):
"""
A ModelSerializer that takes an additional `fields` argument that
controls which fields should be displayed.
"""
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)
class BldgLocationAndFilters(DynamicFieldsModelSerializer):
latitude = fields.FloatField(source='lat_016_decimal')
longitude = fields.FloatField(source='long_017_decimal')
class Meta:
model = Bldg
fields = ('latitude', 'longitude')
我想做一些修改 DynamicFieldsModelSerializer 的事情,以便可以将字段附加到已经过滤掉的集合中,但看起来 Meta 字段覆盖了所有内容,因此无法添加任何内容(只能删除字段
所需行为的伪代码:
class DynamicFieldsUnionModelSerializer(ModelSerializer):
"""
A ModelSerializer that takes an additional `fields` argument that
controls which fields should be displayed.
"""
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:
new_fields = set(fields)
existing = set(self.fields)
unique_new = new_fields.union(existing) - existing
for field_name in unique_new:
self.fields.update(field_name)
如果 BldgLocationAndFilters
被调用为 serializer = BldLocationAndFilters(fields=['type'])
,我希望结果 returns 具有 fields = ('latitude', 'longitude', 'type')
DynamicFieldsModelSerializer
仅适用于删除现有字段,因为实现取决于已在 __init__
中构建的字段。您可以在 __init__
之后添加字段,但您必须以某种方式重新构建它们(不仅仅是添加名称)。
但支持这一点的一种方法是覆盖序列化程序的 get_field_names
方法,该方法与未构建的字段名称一起使用:
class BldgLocationAndFilters(ModelSerializer):
latitude = fields.FloatField(source='lat_016_decimal')
longitude = fields.FloatField(source='long_017_decimal')
class Meta:
model = Bldg
fields = ('latitude', 'longitude')
def __init__(self, *args, **kwargs):
# Don't pass the 'fields' arg up to the superclass
self._fields_to_add = kwargs.pop('fields', None)
super().__init__(*args, **kwargs)
def get_field_names(self, *args, **kwargs):
original_fields = super().get_field_names(*args, **kwargs)
if self._fields_to_add:
return set(list(original_fields) + list(self._fields_to_add))
return original_fields
# Should use latitude, longitude, and type
BldgLocationAndFilters(instance, fields=('type',)).data
请注意,这仅使用 ModelSerializer
。
或者只用 __all__
定义序列化程序(同时仍然使用 DynamicFieldsModelSerializer
)并根据需要设置字段:
class BldgLocationAndFilters(DynamicFieldsModelSerializer):
latitude = fields.FloatField(source='lat_016_decimal')
longitude = fields.FloatField(source='long_017_decimal')
class Meta:
model = Bldg
fields = '__all__'
BldgLocationAndFilters(instance, fields=('latitude', 'longitude', 'type')).data
我正在尝试编写一个序列化程序,它将采用动态字段并将它们添加到 Meta
中指定的限制数量的字段中,但似乎没有方法可以将字段“添加回”创建后的序列化程序。
class DynamicFieldsModelSerializer(ModelSerializer):
"""
A ModelSerializer that takes an additional `fields` argument that
controls which fields should be displayed.
"""
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)
class BldgLocationAndFilters(DynamicFieldsModelSerializer):
latitude = fields.FloatField(source='lat_016_decimal')
longitude = fields.FloatField(source='long_017_decimal')
class Meta:
model = Bldg
fields = ('latitude', 'longitude')
我想做一些修改 DynamicFieldsModelSerializer 的事情,以便可以将字段附加到已经过滤掉的集合中,但看起来 Meta 字段覆盖了所有内容,因此无法添加任何内容(只能删除字段
所需行为的伪代码:
class DynamicFieldsUnionModelSerializer(ModelSerializer):
"""
A ModelSerializer that takes an additional `fields` argument that
controls which fields should be displayed.
"""
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:
new_fields = set(fields)
existing = set(self.fields)
unique_new = new_fields.union(existing) - existing
for field_name in unique_new:
self.fields.update(field_name)
如果 BldgLocationAndFilters
被调用为 serializer = BldLocationAndFilters(fields=['type'])
,我希望结果 returns 具有 fields = ('latitude', 'longitude', 'type')
DynamicFieldsModelSerializer
仅适用于删除现有字段,因为实现取决于已在 __init__
中构建的字段。您可以在 __init__
之后添加字段,但您必须以某种方式重新构建它们(不仅仅是添加名称)。
但支持这一点的一种方法是覆盖序列化程序的 get_field_names
方法,该方法与未构建的字段名称一起使用:
class BldgLocationAndFilters(ModelSerializer):
latitude = fields.FloatField(source='lat_016_decimal')
longitude = fields.FloatField(source='long_017_decimal')
class Meta:
model = Bldg
fields = ('latitude', 'longitude')
def __init__(self, *args, **kwargs):
# Don't pass the 'fields' arg up to the superclass
self._fields_to_add = kwargs.pop('fields', None)
super().__init__(*args, **kwargs)
def get_field_names(self, *args, **kwargs):
original_fields = super().get_field_names(*args, **kwargs)
if self._fields_to_add:
return set(list(original_fields) + list(self._fields_to_add))
return original_fields
# Should use latitude, longitude, and type
BldgLocationAndFilters(instance, fields=('type',)).data
请注意,这仅使用 ModelSerializer
。
或者只用 __all__
定义序列化程序(同时仍然使用 DynamicFieldsModelSerializer
)并根据需要设置字段:
class BldgLocationAndFilters(DynamicFieldsModelSerializer):
latitude = fields.FloatField(source='lat_016_decimal')
longitude = fields.FloatField(source='long_017_decimal')
class Meta:
model = Bldg
fields = '__all__'
BldgLocationAndFilters(instance, fields=('latitude', 'longitude', 'type')).data