Я работаю в компании, которая использует машины и формы для производства промышленных деталей. Во время производственного процесса машины могут работать со сбоями, поэтому мы создали интерфейс и серверную часть, чтобы работники регистрировали эти записи об ошибках. Недавно к этой системе присоединились инженеры и менеджеры из других отделов, поэтому мне нужно было убедиться, кто что может делать, другими словами, управлять разрешениями .
Соответствующая модель:
class FaultRecord(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.PROTECT)
fault = models.ForeignKey(Fault, on_delete=models.PROTECT)
machine = models.ForeignKey(Machine, on_delete=models.PROTECT)
mold = models.ForeignKey(Mold, on_delete=models.PROTECT)
part = models.ForeignKey(Part, on_delete=models.PROTECT)
material = models.ForeignKey(Material, on_delete=models.PROTECT)
responsible_departments = models.ManyToManyField(Department)
status = models.ForeignKey(FaultRecordStatus, on_delete=models.SET_NULL, null=True)
reason = models.TextField()
temporary_action = models.TextField()
permanent_action = models.TextField(null=True)
duration = models.PositiveSmallIntegerField()
occured_at = models.DateTimeField()
created_at = models.DateTimeField()
updated_at = models.DateTimeField(null=True)
Соответствующий вид:
class FaultRecordViewSet(ModelViewSet):
authentication_classes = [TokenAuthentication]
permission_classes = [IsAuthenticated, ModelPermission]
serializer_class = FaultRecordSerializer
queryset = FaultRecord.objects.prefetch_related(
'user',
'fault',
'machine',
'mold',
'part',
'material',
'responsible_departments',
'status'
).all().order_by('occured_at')
model = FaultRecord
Как мы знаем, Django создает 4 разрешения по умолчанию для моделей, которые позволяют просматривать, добавлять, изменять и удалять. Исходя из этого, я хотел проверить разрешения пользователей по методу запроса, поэтому мне не нужно писать класс разрешений для каждой модели. Также я не хочу использовать has_object_permission, потому что я тоже проверяю разрешение на публикацию.
Решение, которое я нашел:
class ModelPermission(BasePermission):
method_mapper = {
'GET': 'view',
'POST': 'add',
'PUT': 'change',
'PATCH': 'change',
'DELETE': 'delete'
}
def get_model_permission(self, method, model):
app_label = model._meta.app_label
model_name = model._meta.model_name
permission_name = self.method_mapper.get(method)
return f'{app_label}.{permission_name}_{model_name}'
def has_permission(self, request, view):
if request.method in SAFE_METHODS:
return True
permission = self.get_model_permission(request.method, view.model)
return request.user.has_perm(permission)
Я добавил атрибут модели для класса просмотра, поэтому get_model_permission возвращает требуемую строку, чтобы иметь возможность использовать has_perm для меня. С его помощью я могу создавать группы с разрешениями и устанавливать группы пользователей. Я много искал, но ничего полезного не нашел. Что вы думаете? Мне нужны мнения других.