Как обрабатывать предварительный выбор связанных полей и обеспечить правильное обновление отношений «многие ко многим» вPython

Программы на Python
Ответить
Anonymous
 Как обрабатывать предварительный выбор связанных полей и обеспечить правильное обновление отношений «многие ко многим» в

Сообщение Anonymous »

Я работаю над реализацией управления доступом на основе ролей с использованием Django и Django Rest Framework. Я хочу создать роль с набором разрешений через API просмотра DRF. Кроме того, мне нужна функция обновления этих разрешений, включая добавление новых и удаление существующих. При отображении роли в просматриваемом API я хочу, чтобы связанные с ней разрешения были предварительно выбраны для ясности, а также отображались все остальные доступные разрешения для удобства добавления.
Что у меня есть на данный момент сделано
Вот упрощенная версия моей модели

Код: Выделить всё

class BaseModel(models.Model):
pkid = models.BigAutoField(primary_key=True, editable=False)
id = models.UUIDField(default=uuid.uuid4, editable=False, unique=True)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
is_active = models.BooleanField(default=True)

class Meta:
abstract = True

class Role(BaseModel):
name = models.CharField(max_length=100)

class Permission(BaseModel):
name = models.CharField(max_length=100, unique=True)
description = models.TextField(null=True, blank=True)

class RolePermission(BaseModel):
role = models.ForeignKey(
Role, on_delete=models.CASCADE, related_name="role_permissions"
)
permission = models.ForeignKey(Permission, on_delete=models.CASCADE)
Вот мой сериализатор

Код: Выделить всё

class RoleSerializer(serializers.ModelSerializer):
permissions = serializers.SlugRelatedField(
queryset=Permission.objects.all(), many=True, required=False, slug_field="name"
)
business = serializers.PrimaryKeyRelatedField(
queryset=Business.objects.all(), required=False, allow_null=True
)

class Meta:
model = Role
fields = ("id", "name", "is_default", "permissions", "business")

def to_representation(self, instance):
representation = super().to_representation(instance)
permissions = instance.role_permissions.all().values_list(
"permission__name", flat=True
)
representation["permissions"] = list(permissions)
return representation

def to_internal_value(self, data):
data = data.copy()
permissions_data = data.pop("permissions", [])
permissions_qs = Permission.objects.filter(name__in=permissions_data)
data["permissions"] = [permission.id for permission in permissions_qs]
return super().to_internal_value(data)
Предварительный выбор работает и все такое, но когда я отправляю запрос UPDATE на изменение разрешений, я получаю такие ошибки, как:

Код: Выделить всё

{
"permissions": [
"Object with name=[UUID('e4ac49c0-093a-4281-96b0-0846917fc62b')] does not exist."
]
}
Я исправил ошибку, переписав свой сериализатор примерно так

Код: Выделить всё

class RoleSerializer(serializers.ModelSerializer):
permissions = serializers.PrimaryKeyRelatedField(
queryset=Permission.objects.all(), many=True, required=False
)
business = serializers.PrimaryKeyRelatedField(
queryset=Business.objects.all(), required=False, allow_null=True
)

class Meta:
model = Role
fields = ("id", "name", "is_default", "permissions", "business")

def to_representation(self, instance):
representation = super().to_representation(instance)
permissions = instance.role_permissions.all().values_list(
"permission", flat=True
)
representation["permissions"] = list(permissions)
return representation

def to_internal_value(self, data):
data = data.copy()
permissions_data = data.pop("permissions", [])
internal_value = super().to_internal_value(data)
internal_value["permissions"] = permissions_data
return internal_value
но это повлияет на возвращаемый json, теперь вместо имени разрешения я получаю такие идентификаторы

Код: Выделить всё

{
"id": "0b3de100-82ef-4a02-b94e-659cb6dd4314",
"name": "neweee",
"is_default": false,
"business": null,
"permissions":  [
1,
2
]
}
Мой вопрос: Как я могу правильно предварительно выбрать связанные поля (разрешения) в качестве имен в API просмотра DRF, сохраняя при этом возможность создавать/обновлять с помощью нет ошибок?
Спасибо

Подробнее здесь: https://stackoverflow.com/questions/791 ... -of-many-t
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Python»