Django Rest Framework: KeyError при переопределении функции 'update' в сериализаторе
У меня есть модель User и модель Group, которые представлены ниже:
class User(models.Model):
username = models.CharField(primary_key=True, max_length=32, unique=True)
user_email = models.EmailField(max_length=32, unique=False)
user_password = models.CharField(max_length=32)
user_avatar_path = models.CharField(max_length=64)
class Group(models.Model):
group_id = models.AutoField(primary_key=True)
group_name = models.CharField(max_length=32, unique=False)
group_admin = models.ForeignKey(User, on_delete=models.CASCADE, related_name='my_groups')
members = models.ManyToManyField(User, related_name='groups', through='UserGroup')
Каждая группа может иметь несколько пользователей, связанных с ней, и каждый пользователь может быть связан с несколькими группами, что моделируется с помощью ManyToManyField и сквозной модели между моделями. Когда я создаю группу, пользователь, который создает группу, автоматически назначается администратором группы и, следовательно, добавляется как член группы:
class MemberSerializer(serializers.ModelSerializer): # The nested serializer used within the GroupSerializer
username = serializers.ReadOnlyField(source='user.username')
class Meta:
model = User
fields = ['username']
class GroupSerializer(serializers.ModelSerializer):
members = MemberSerializer(source='user_groups', many=True, required=False)
group_admin = serializers.SlugRelatedField(slug_field='username', queryset=User.objects.all()) # A Group object is related to a User object by username
class Meta:
model = Group
fields = ['group_id', 'group_name', 'group_admin', 'members']
def create(self, validated_data): # Overriden so that when a group is created, the group admin is automatically declared as a member.
group = Group.objects.create(**validated_data)
group_admin_data = validated_data.pop('group_admin')
group.members.add(group_admin_data)
return group
def update(self, instance, validated_data):
members_data = validated_data.pop('members') # Comes from the request body
group_id = self.kwargs['group_id'] # Comes from the URL
add_remove = self.kwargs['add_remove'] # Comes from the URL
group = Group.objects.filter(group_id=group_id).first()
if members_data is not None:
if add_remove == 'add':
for member in members_data:
group.members.add(member['username'])
elif add_remove == 'remove':
for member in members_data:
group.members.remove(member['username'])
return super().update(instance, validated_data)
Добавление пользователя, создавшего группу (администратора группы), в качестве члена группы успешно выполняется путем переопределения метода create в GroupSerializer и последующего выполнения запроса POST, как показано ниже:
{
"group_name": "StackOverFlow",
"group_admin": "bigboy"
}
# which then results in the response when the group has been successfully created:
{
"group_id": 1,
"group_name": "StackOverFlow",
"group_admin": "bigboy",
"members": [
{
"username": "bigboy"
}
]
}
Я хочу иметь возможность обновлять членов группы через запрос PATCH, добавляя или удаляя пользователей, связанных с группой. Я попытался сделать это, переопределив метод update в GroupSerializer, как показано выше. Запрос PATCH выполняется, как показано ниже, с url http://127.0.0.1:8000/group/1/add/update для добавления пользователя в группу:
{
"members": [
{
"username": "small_man"
}
]
}
Полученная ошибка:
line 47, in update
members_data = validated_data.pop('members') # Comes from the request body
KeyError: 'members'
Я не уверен, что метод, которым я пытаюсь добавить пользователя в группу, является простым или даже действительным методом, но KeyError сбивает с толку, поскольку я предполагаю, что проверенные данные включают members список.
Когда вы используете аргумент source, вы можете получить доступ к данным, используя значение источника в качестве ключа, попробуйте следующее:
def update(self, instance, validated_data):
members_data = validated_data.pop('user_groups')