使用django rest framework 3.6
我使用的前端库是x-editable
,它需要知道该字段的数据类型。
我目前正在使用Django Rest Framework和Serializers获取数据。我搜索过Serializer Field,但我很难理解它是否符合我的要求。此外,我不知道如何进行测试。
基本上我有一个端点试图获取SomeModel及其5个相关模型的单个实例。 /api/v1.0/shape/2508
这没关系,我得到了一个像这样的数据结构:
{
"data": {
"art_numbers": [],
"collection": "",
"extra_number": "",
"some_related_model1": {
"finished_capacity": null,
"finished_weight": null,
"finished_width": null,
"id": 3
},
"has_associated_product_variant": false,
"id": 2508,
"another_related_model": {
"bar_height": null,
"bar_number": "",
"id": 3,
}
}
}
还有一种方法可以让django restframework传递一些关于相关模型字段的元数据吗?喜欢数据类型吗?
我正在寻找的最小值是能够取回相关模型中字段的数据类型。
我希望能够检测到数字,普通字段,文本字段
答案 0 :(得分:3)
Django Rest Framework有metadata classes.但你可以augment it with another library调用drf-schema-adapte r。
'DEFAULT_METADATA_CLASS': 'drf_auto_endpoint.metadata.AutoMetadata',
添加到您的REST_FRAMEWORK
设置DRF_AUTO_METADATA_ADAPTER = 'drf_auto_endpoint.adapters.ReactJsonSchemaAdapter'
它应该是这样的:
REST_FRAMEWORK = {
'DEFAULT_RENDERER_CLASSES': (
'rest_framework.renderers.JSONRenderer',
),
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.IsAuthenticated',
],
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.TokenAuthentication',
'rest_framework.authentication.SessionAuthentication',
],
'DEFAULT_METADATA_CLASS': 'drf_auto_endpoint.metadata.AutoMetadata',
'TEST_REQUEST_DEFAULT_FORMAT': 'json',
'PAGE_SIZE': 20,
'SEARCH_PARAM': 'q'
}
DRF_AUTO_METADATA_ADAPTER = 'drf_auto_endpoint.adapters.ReactJsonSchemaAdapter'
选择ReactJsonSchemaAdapter纯属个人偏好。您还可以坚持使用DRF本身的SimpleMetadata。
使用类似邮递员的东西来测试相同的网址,但使用OPTIONS作为方法
你应该得到这样的东西:
{
"data": {
"name": "Shape Detail",
"description": "Retrieve a shape by its id.",
"renders": [
"application/json"
],
"parses": [
"application/json",
"application/x-www-form-urlencoded",
"multipart/form-data"
],
"actions": {
"PUT": {
"id": {
"type": "integer",
"required": false,
"read_only": true,
"label": "ID"
},
"name": {
"type": "string",
"required": true,
"read_only": false,
"label": "Shape Name",
"max_length": 100
},
"name_en": {
"type": "string",
"required": false,
"read_only": false,
"label": "Shape Name [en]",
"max_length": 100
},
"name_zh_hans": {
"type": "string",
"required": false,
"read_only": false,
"label": "Shape Name [zh-hans]",
"max_length": 100
},
"serial_number": {
"type": "string",
"required": false,
"read_only": false,
"label": "Shape Number",
"max_length": 100
},
"shape_variant_number": {
"type": "string",
"required": false,
"read_only": false,
"label": "Shape Variant Number",
"max_length": 100
},
"collection": {
"type": "string",
"required": false,
"read_only": false,
"label": "Collection",
"max_length": 255
},
"qr_code": {
"type": "string",
"required": false,
"read_only": false,
"label": "QR Code",
"max_length": 255
},
"extra_number": {
"type": "string",
"required": false,
"read_only": false,
"label": "Extra Number",
"max_length": 255
},
"art_numbers": {
"type": "field",
"required": false,
"read_only": false,
"label": "Art numbers"
},
"remark": {
"type": "string",
"required": false,
"read_only": false,
"label": "Remark",
"max_length": 400
},
"has_associated_product_variant": {
"type": "field",
"required": false,
"read_only": true,
"label": "Has associated product variant"
},
"shape_benchmark": {
"type": "nested object",
"required": false,
"read_only": false,
"label": "Shape benchmark",
"children": {
"id": {
"type": "integer",
"required": false,
"read_only": true,
"label": "ID"
},
"up_spin_speed": {
"type": "string",
"required": false,
"read_only": false,
"label": "Up Spin Speed",
"max_length": 15
},
如果我了解更多
,我会添加更多细节答案 1 :(得分:1)
class ModelSerializer(serializers.ModelSerializer):
def to_representation(self, instance):
"""
add type for Related model
"""
ret = OrderedDict()
fields = [field for field in self.fields.values() if not field.write_only]
for field in fields:
try:
key = field.get_attribute(instance)
except SkipField:
continue
value = field.to_representation(key)
if isinstance(field, ModelSerializer):
value_type = {}
for k, v in value.items():
value_type[k+'_type'] = type(v).__name__
value.update(value_type)
ret[field.field_name] = value
for field in self.context:
# context defaults to including 'request', 'view' and 'format' keys.
if field not in ['request', 'view', 'format']:
ret[field] = self.context[field]
return ret
serializers.py:
class UserListSerializer(ModelSerializer):
class Meta:
model = User
fields = ('id', 'username', 'portrait', 'gender', 'tel', 'get_gender_display', 'get_full_name')
class MessageSerializer(ModelSerializer):
from_user = UserListSerializer(read_only=True)
to_user = UserListSerializer(read_only=True)
class Meta:
model = Message
fields = '__all__'
获取网址http://192.168.1.108/message/3
我可以获得:
{
"id": 3,
"from_user": {
"id": 1,
"username": "schoolms",
"portrait": "http://192.168.1.108/media/default/user/default.png",
"gender": 2,
"tel": "",
"get_gender_display": "x",
"get_full_name": "schoolms",
"tel_type": "str",
"gender_type": "int",
"id_type": "int",
"get_full_name_type": "str",
"portrait_type": "str",
"get_gender_display_type": "str",
"username_type": "str"
},
"to_user": {
"id": 2,
"username": "x1",
"portrait": "http://192.168.1.108/media/user/20171012-102543-778.png",
"gender": 2,
"tel": "",
"get_gender_display": "x",
"get_full_name": "x1",
"tel_type": "str",
"gender_type": "int",
"id_type": "int",
"get_full_name_type": "str",
"portrait_type": "str",
"get_gender_display_type": "str",
"username_type": "str"
},
"subject": "x1",
"content": "x2",
"is_read": 0,
"from_user_abandon": false,
"to_user_abandon": false,
"create_time": "2017-10-18 17:50:44",
"update_time": "2017-10-18 17:50:44"
}