JavaRush /Курси /Модуль 3: Django /Налаштування полів для серіалізації

Налаштування полів для серіалізації

Модуль 3: Django
Рівень 17 , Лекція 3
Відкрита

Коли ти розробляєш API, завжди є ситуації, коли тобі не потрібні всі поля з моделі. Іноді ти хочеш приховати чутливі дані, зробити поле тільки для читання або додати додаткову валідацію. DRF надає потужні інструменти для управління цими нюансами.

Наприклад, тобі може знадобитися:

  • Обмежити доступ до конфіденційних полів (наприклад, приховати пароль користувача).
  • Зробити поле доступним тільки для читання, щоб його не можна було змінити через API.
  • Налаштувати поле для повернення даних у зручному форматі (наприклад, форматувати дату).

Час починати. Адже, як кажуть, «хороший код — це читабельний код, а хороший API — це налаштовуваний API».

Налаштування полів у серіалізаторі

Основний спосіб керувати списком полів (видаляти або додавати) у серіалізаторі — це використовувати атрибут fields у класі Meta.

from rest_framework import serializers
from myapp.models import Product

class ProductSerializer(serializers.ModelSerializer):
    class Meta:
        model = Product
        fields = ['id', 'name', 'price']  # Вказуємо тільки потрібні поля

Якщо тобі потрібно виключити одне або кілька полів, використовуй атрибут exclude:

class ProductSerializer(serializers.ModelSerializer):
    class Meta:
        model = Product
        exclude = ['discount']  # Виключаємо поле "discount"
❗ Важливо:

атрибути fields та exclude є взаємовиключними. Не намагайся вказати їх обидва одночасно, інакше DRF «образиться» і видасть помилку.

Поля тільки для читання та запису

Ти можеш керувати доступом до полів за допомогою параметрів read_only_fields або write_only_fields.

Приклад: поле тільки для читання. Поле доступне клієнту тільки під час відправки даних, але змінювати його через API не можна.

class ProductSerializer(serializers.ModelSerializer):
    class Meta:
        model = Product
        fields = ['id', 'name', 'price', 'created_at']
        read_only_fields = ['created_at']  # Поле "created_at" тільки для читання

Приклад: поле тільки для запису. Поле можна відправити на сервер, але воно не буде повертатися клієнту.

class ProductSerializer(serializers.ModelSerializer):
    class Meta:
        model = Product
        fields = ['id', 'name', 'password'] 
        extra_kwargs = {'password': {'write_only': True}}  # "password" - тільки для запису

extra_kwargs — універсальний спосіб додати кастомну поведінку для окремих полів.

Кастомізація полів

Якщо тобі потрібно змінити поведінку поля (наприклад, його тип чи параметри), можна визначити поле явно. Це може бути корисно, якщо ти хочеш налаштувати його атрибути.

Наведемо приклад. Припустимо, потрібно обмежити мінімальне та максимальне значення для ціни товару:

class ProductSerializer(serializers.ModelSerializer):
    price = serializers.DecimalField(max_digits=10, decimal_places=2, min_value=0)

    class Meta:
        model = Product
        fields = ['id', 'name', 'price']

Коли клієнт відправить від'ємне значення, він отримає помилку валідації. І це прекрасно, адже ми захистили нашу базу даних від «мінусових цінників».

Валідація полів

DRF підтримує вбудовані валідатори та дозволяє легко додавати кастомні перевірки для полів.

Використовуйте вбудовані валідатори для стандартних перевірок: довжина рядка, діапазон чисел тощо.

class ProductSerializer(serializers.ModelSerializer):
    name = serializers.CharField(max_length=100, min_length=3)
    price = serializers.DecimalField(max_digits=10, decimal_places=2, min_value=1)

    class Meta:
        model = Product
        fields = ['id', 'name', 'price']

Для кастомних перевірок можна визначити метод validate_<field_name>:

class ProductSerializer(serializers.ModelSerializer):
    class Meta:
        model = Product
        fields = ['id', 'name', 'price']

    def validate_price(self, value):
        if value > 10000:
            raise serializers.ValidationError("Ціна не може бути більше 10,000.")
        return value

Метод повертає значення, якщо воно пройшло валідацію.

Приховування полів

Іноді ви взагалі не хочете показувати певне поле клієнту. Наприклад, поле internal_code потрібно тільки для внутрішнього використання.

Приклад. Ви можете просто не включати це поле до списку fields. Однак, якщо потрібно більш гнучке рішення, раптово на допомогу приходить SerializerMethodField.

class ProductSerializer(serializers.ModelSerializer):
    internal_code = serializers.SerializerMethodField()

    class Meta:
        model = Product
        fields = ['id', 'name', 'price']

    def get_internal_code(self, obj):
        return None  # Ми повернемо "None", щоб клієнту здалося, що це поле не існує

Робота з додатковою інформацією

Іноді потрібно включити в серіалізатор обчислюване поле. Наприклад, додамо до товару поле total_price, яке розраховується на основі ціни та кількості:

class ProductSerializer(serializers.ModelSerializer):
    total_price = serializers.SerializerMethodField()

    class Meta:
        model = Product
        fields = ['id', 'name', 'price', 'quantity', 'total_price']

    def get_total_price(self, obj):
        return obj.price * obj.quantity

Використовуйте SerializerMethodField для обчислюваних значень або даних, які не зберігаються у базі.

Поля з користувацькими форматами

Що, якщо клієнту потрібно повернути дату у специфічному форматі? Наприклад, замість стандартного ISO формату, нам потрібен DD/MM/YYYY.

class ProductSerializer(serializers.ModelSerializer):
    created_at = serializers.DateTimeField(format="%d/%m/%Y")

    class Meta:
        model = Product
        fields = ['id', 'name', 'price', 'created_at']

Тепер клієнт отримає дату у зручному для нього вигляді.

Практичне завдання

Тепер, коли ви освоїли налаштування полів у серіалізаторах, спробуйте наступні завдання:

  1. Створіть серіалізатор для моделі користувача, включаючи тільки поля id, username, та email. Поле email має бути доступним тільки для читання.
  2. Розширте модель товару, додавши поле discount_price, яке обчислюється як price * (1 - discount/100) з використанням SerializerMethodField.
  3. Налаштуйте валідацію, щоб поле discount не перевищувало 50%.

Ці завдання допоможуть закріпити матеріал. А якщо щось не виходить, просто уявіть, як ваш майбутній API тішить клієнтів. Ну хто не старається заради такої мотивації? 😄

Тепер ви знаєте, як керувати полями серіалізаторів у Django REST Framework. Попереду нас чекають більш складні завдання — вкладені серіалізатори та робота з пов’язаними об’єктами!

Коментарі
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ