Как обновить с помощью SerializerMethodField в Django Rest Framework - PullRequest
1 голос
/ 04 августа 2020

У меня есть поле в моем ModelSerializer, которое я установил как SerializerMethodField, чтобы изменить поведение получения для поля. Раньше я мог обновлять данные, теперь не могу. Как я могу решить эту проблему?

Первоначально, без использования SerializerMethodField, я получил такие данные:

    {
        ...
        "members": [2,3],
        ...
    }

, но я добавил SerializerMethodField для изменения данных, затем обновление перестало работать.

models.py

# Create your models here.
class Company(models.Model):
    members = ArrayField(models.IntegerField(blank=True), blank=True)
...

serializers.py

class AccountSerializer(serializers.ModelSerializer):
    user=serializers.StringRelatedField(read_only=False)
    class Meta:
        model=Account
        fields='__all__'

class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = '__all__'

class CompanySerializer(serializers.ModelSerializer):
    user = UserSerializer(read_only=False)
    members = serializers.SerializerMethodField()
    class Meta:
        model = Company
        fields = '__all__' #('id', 'name', 'description', 'date_created', 'user', 'status', 'theme', 'members')

    def get_members(self, obj):
        accounts = Account.objects.filter(id__in=obj.members)
        return AccountSerializer(accounts, many=True).data
...

1 Ответ

1 голос
/ 05 августа 2020
  1. Вам нужно использовать разные сериализаторы для обновления и создания. Этот сериализатор работает только для получения.

  2. Или вы можете создать настраиваемое поле. Django Rest Framework Как обновить SerializerMethodField

  3. Или могут быть другие более простые ловушки. Если 'create' и 'update' работали так, как вы хотели перед изменением members, вы можете сделать следующее, чтобы вернуть все к значениям по умолчанию для запросов на создание и обновление.

  • Переопределите метод __init__. .
class CompanySerializer(serializers.ModelSerializer):
    user = UserSerializer(read_only=False)

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        try:
            if self.context['request'].method in ['GET']:
                self.fields['members'] = SerializerMethodField()
        except KeyError:
            pass

    class Meta:
        model = Company
        fields = '__all__' #('id', 'name', 'description', 'date_created', 'user', 'status', 'theme', 'members')

    def get_members(self, obj):
        accounts = Account.objects.filter(id__in=obj.members)
        return AccountSerializer(accounts, many=True).data
...
  • Или вы можете создать другое поле для получения участников.
class CompanySerializer(serializers.ModelSerializer):
    user = UserSerializer(read_only=False)
    members_data = SerializerMethodField()

    class Meta:
        model = Company
        fields = ('id', 'name', 'description', 'date_created', 'user', 'status', 'theme', 'members', 'members_data')

    def get_members_data(self, obj):
        accounts = Account.objects.filter(id__in=obj.members)
        return AccountSerializer(accounts, many=True).data
...
...