我正在使用Django Rest Framework(以及rest_framework_mongoengine)并覆盖我的序列化程序的 to_representation()以发回我自己的自定义JSON对象。一切正常,但JSON字段的顺序搞砸了。请告诉我如何重新排序/重组正在发送回的JSON对象。序列化器看起来像这样:
`arm-none-eabi-gcc -Wall -g -std=c99 -Os -mlittle-endian -mcpu=cortex-m4 -march=armv7e-m -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=hard -ffunction-sections -fdata-sections -Itemplate/inc -Icube/Drivers/BSP/STM32F4-Discovery -Icube/Drivers/CMSIS/Include -Icube/Drivers/CMSIS/Device/ST/STM32F4xx/Include -Icube/Drivers/STM32F4xx_HAL_Driver/Inc -Icube/Middlewares/ST/STM32_USB_Device_Library/Core/Inc -Icube/Middlewares/ST/STM32_USB_Device_Library/Class/HID/Inc -DSTM32F407xx -DUSE_HAL_DRIVER -DUSE_DBPRINTF -mthumb-interwork -Wl,--gc-sections -Wl,-Map=demo.map -Lcube/Drivers/CMSIS/Lib -Ttemplate/stm32f401xc.ld --specs=rdimon.specs -lc -lrdimon template/src/startup_stm32f401xc.s template/obj/main.o template/obj/system_stm32f4xx.o template/obj/stm32f4xx_it.o template/obj/usbd_conf_template.o template/obj/usbd_core.o template/obj/usbd_ctlreq.o template/obj/usbd_ioreq.o template/obj/usbd_hid.o template/obj/usbd_desc.o template/obj/stm32f4xx_hal_pcd.o template/obj/stm32f4_discovery_accelerometer.o template/obj/stm32f4xx_hal_tim.o -o demo.elf -Lcube/Drivers/STM32F4xx_HAL_Driver -lstm32f4_hal -Lcube/Drivers/BSP/STM32F4-Discovery -lstm32f4_bsp'
我得到的回应是:
class PharmacySerializer(DocumentSerializer):
bank_account = serializers.DictField(child=serializers.CharField(), required=False)
class Meta:
model = Pharmacy
fields = (
'id', 'name', 'email', 'mobile', 'address_line_1', 'address_line_2',
'city', 'state', 'zip', 'created_by', 'created_on', 'last_updated_by', 'license_number',
'bank_account', 'last_updated_on', 'is_email_verified', 'is_mobile_verified', 'is_active')
read_only_fields = ('created_by', 'created_on', 'last_updated_by', 'last_updated_on', 'is_active')
def to_representation(self, pharmacy):
return {
'id': str(pharmacy.id),
'name': pharmacy.name,
'email': pharmacy.email,
'mobile': pharmacy.mobile,
'address_line_1': pharmacy.address_line_1,
'address_line_2': pharmacy.address_line_2,
'city': pharmacy.city,
'state': pharmacy.state,
'zip': pharmacy.zip,
'created_by': pharmacy.created_by,
'created_on': pharmacy.created_on,
'last_updated_by': pharmacy.last_updated_by,
'license_number': pharmacy.license_number,
'bank_account': {
'bank_name': pharmacy.bank_account.bank_name,
'account_number': pharmacy.bank_account.account_number,
'account_type': pharmacy.bank_account.account_type
},
'last_updated_on': pharmacy.last_updated_on,
'is_email_verified': pharmacy.is_email_verified,
'is_mobile_verified': pharmacy.is_mobile_verified,
'is_active': pharmacy.is_active
}
我希望它与to_representation()
的返回词典的顺序相同答案 0 :(得分:3)
尝试在to_representation
中返回OrderedDict:
def to_representation(self, pharmacy):
return OrderedDict([('id', str(pharmacy.id),), ...])
代码中的dict对象本质上没有排序。假设框架在内部使用json.dump
,您可以使用建议here的有序对象来保持订单。
答案 1 :(得分:3)
If you want to maintain order of response keys, you can use an OrderedDict
. But there is one thing you should remember about OrderedDicts
:
OrderedDict maintains order only while insertion of keys. The order gets lost while initializing with kwargs.
From Python docs:
The
OrderedDict
constructor andupdate()
method both accept keyword arguments, but their order is lost because Python’s function call semantics pass-in keyword arguments using a regular unordered dictionary.
You need to first create an OrderedDict
instance and then add keys one by one.
from collections import OrderedDict
def to_representation(self, pharmacy):
ret = OrderedDict() # initialize on ordereddict
# insert keys one by one in desired oreder
ret['id'] = str(pharmacy.id)
ret['name'] = pharmacy.name
ret['email'] = pharmacy.email
ret['mobile'] = pharmacy.mobile
ret['address_line_1'] = pharmacy.address_line_1
ret['address_line_2'] = pharmacy.address_line_2
ret['city'] = pharmacy.city
ret['state'] = pharmacy.state
ret['zip'] = pharmacy.zip
ret['created_by'] = pharmacy.created_by
ret['created_on'] = pharmacy.created_on
ret['last_updated_by'] = pharmacy.last_updated_by
ret['license_number'] = pharmacy.license_number
ret['bank_account'] = {
'bank_name' = pharmacy.bank_account.bank_name
'account_number' = pharmacy.bank_account.account_number
'account_type' = pharmacy.bank_account.account_type
}
ret['last_updated_on'] = pharmacy.last_updated_on
ret['is_email_verified'] = pharmacy.is_email_verified
ret['is_mobile_verified'] = pharmacy.is_mobile_verified
ret['is_active'] = pharmacy.is_active
return ret
NOTE: Another option(recommended) is to use EmbeddedDocumentSerializer
for bank_account
field. Then you won't need to override the to_representation()
method.