DRF - массив целых чисел - PullRequest
1 голос
/ 18 июня 2020

Мне нужно отправить массив целых чисел в сериализатор DRF.

Сериализатор:

class ItemSerializer(serializers.Serializer):
    id = serializers.IntegerField(required = False)
    selected_items = serializers.ListField(child = serializers.IntegerField())

Из FE я просто отправляю массив с помощью машинописного текста:

createItem () {
    let tmp: any = {};
    const itemData = new FormData();
    itemData.append('id',1);
    itemData.append('selected_items', this.current.selected_items.map( e => e.id))

    return this.itemService.createItem( itemData )
        .subscribe( data => this.goBack( data ),
            err => {
                console.log( err );
                this.toastr.error( 'Item not saved', 'Error' )
            } );
}

itemService.createItem выполняет только http.post

Когда FE отправляет данные в BE, поле selected_items кодируется как selected_items=1,2 (проверено с помощью wirehark). Когда данные анализируются из DRF, поле кодируется как selected_items=['1,2']. Таким образом, поле не проверяется, потому что 1,2 не является действительным целым числом.

1 Ответ

0 голосов
/ 19 июня 2020
• 1000 .
class ItemSerializer(serializers.Serializer):
    id = serializers.IntegerField(required = False)
    selected_items = serializers.ListField(child = serializers.IntegerField())

    def to_internal_value(self, data):
        """
        method is called to restore a primitive datatype into its internal python representation. This method should raise a serializers.ValidationError if the data is invalid. 
        reference: https://www.django-rest-framework.org/api-guide/fields/#custom-fields
        """
        # Convert comma separated digits to list of integers
        data['selected_items'] = data['selected_items'].split(',') if data['selected_items'] else []
        return data

или вы можете написать настраиваемую проверку на уровне поля:

class ItemSerializer(serializers.Serializer):
    id = serializers.IntegerField(required = False)
    selected_items = serializers.ListField(child = serializers.IntegerField())

    def validate_selected_items(self, value):
        """
        You can specify custom field-level validation by adding .validate_<field_name> methods to your Serializer subclass.
        reference: https://www.django-rest-framework.org/api-guide/serializers/#field-level-validation
        """
        # Convert comma separated digits to list of integers
        return value.split(',') if value else []
...