Как сериализовать, когда поля неизвестны в django-rest-framework?

Я хочу сериализовать словарь, где имя_поля не фиксировано, оно может быть любым, и мне нужно проверить, является ли тип значения_поля правильным в соответствии с тем, какой тип должен быть указан в имени_поля. например:

{
   "attributes": {
         attribute_name: attribute_vale
         .
         .
         .
         (can contain such more pairs)
   }
}

Есть ли какой-нибудь способ сериализации, который поможет мне сериализовать пару ключ-значение словаря атрибутов?

Вы можете динамически получать поля модели с помощью:

 mymodel._meta.get_fields()

Таким образом, вы можете создавать динамические сериализаторы с:

    def get_serializer(self, include_fields: list[str]=None, readonly_fields: list[str]=None):
        class AnySerializer(ModelSerializer):
            class Meta:
                model = self.__class__
                fields = [field.name for field in self._meta.get_fields()] if not include_fields else include_fields
                read_only_fields = ['pk'] if not readonly_fields else readonly_fields
        return AnySerializer(self, many=False)

как метод в вашей модели. Затем вы можете вызвать:

mymodel = MyModel.objects.all().first() # Get an instance
serializer = mymodel.get_serializer() # Dynamically create a serializer
serialized_data = serializer.data # Serialized JSON data

Вы можете проверить типы, введенные в поле с помощью:

# I'm sure there's a way of dynamically validating the fields before saving. 
# I just don't have that answer.
for field in self._meta.get_fields():
    if field.get_internal_type() is models.EmailField:
        field_data = getattr(self, field.name)
        validate data...
    elif ...

С помощью этого метода можно определить поля, доступные только для чтения, и include_fields. Если ни одно из них не указано, все поля будут сериализованы. Я уверен, что валидация модели Django все еще применяется к сериализаторам, так что вы можете настроить валидацию там.

Это метод для модели, но я сам использую его на кверисетах. (используйте self.model в кверисетах для доступа к модели из кверисета.)

Вернуться на верх