Python >> Tutorial de Python >  >> Python

¿Cómo limitar el acceso al campo en un modelo según el tipo de usuario en Graphene/Django?

CONSULTAS

Asumiendo que tienes

  1. una consulta definida como

    empleados =grafeno.Lista(TipoEmpleado)

  2. un solucionador para la consulta como

    def resolve_employees(self, info, **kwargs):return Employee.objects.all()

y

  1. permisos en su modelo de empleado llamados can_view_salary y can_edit_salary

Luego deberá definir el EmployeeType con un valor de salary que depende del usuario. Algo como

from graphene_django.types import DjangoObjectType
from myapp.models import Employee

class EmployeeType(DjangoObjectType):
    class Meta:
        model = Employee
        
    def resolve_salary(self, info):
        if info.context.user.has_perm('myapp.can_view_salary'):
            return self.salary
        return None

Lo importante es que estás creando un resolve personalizado función para el salario que se cambia en función del valor de un permiso. No necesita crear ningún otro solucionador para first_name y last_name .



MUTACIONES

Lea primero la documentación. Pero no hay un ejemplo para hacer una actualización.

En resumen, este es el enfoque que puede tomar:

  1. Cree un método para configurar el empleado en su Mutation método

    class MisMutaciones(graphene.ObjectType):set_employee =SetEmployee.Field()

  2. Crea un método para SetEmployee que obtiene el objeto Employee y lo actualiza. El campo de salario se ignora para ciertos usuarios. Tenga en cuenta nuevamente que estoy ignorando el Decimal problema tomando una cadena como entrada.

    clase SetEmployee(grafeno.Mutación):

     class Arguments:
         id = graphene.ID()
         first_name = graphene.String()
         last_name = graphene.String()
         salary = graphene.String()
    
     employee = graphene.Field(lambda: EmployeeType)
    
    
     @classmethod
     def mutate(cls, root, info, **args):
         employee_id = args.get('employee_id')
    
         # Fetch the employee object by id
         employee = Employee.objects.get(id=employee_id)
         first_name = args.get('first_name')
         last_name = args.get('last_name')
         salary = args.get('salary')
    
         # Update the employee fields from the mutation inputs
         if first_name:
             employee.first_name = first_name
         if last_name:
             employee.last_name = last_name
         if salary and info.context.user.has_perm('myapp.can_edit_salary'):
             employee.salary = salary
         employee.save()
         return SetEmployee(employee=employee)
    

Gran respuesta @MarkChackerian. Sin embargo, personalmente, creo que devolver un valor nulo para un campo en acceso no autorizado puede ser ambiguo, por lo que personalmente planteo una excepción del método de resolución como esa:

class UnauthorisedAccessError(GraphQLError):
    def __init__(self, message, *args, **kwargs):
        super(UnauthorisedAccessError, self).__init__(message, *args, **kwargs)

def resolve_salary(self, info):
        if info.context.user.has_perm('myapp.can_view_salary'):
            return self.salary
        raise UnauthorisedAccessError(message='No permissions to see the salary!')