在 Django 中为模型设置自定义权限
set custom permission to model in Django
我必须对Django 中的模型设置一些权限,因为我在DRF 中有一些操作,我需要知道用户是否有权限这样做。
我的模型:
class Device(models.Model):
type = models.ForeignKey(Type, on_delete=models.CASCADE)
name = models.fields.CharField(max_length=36)
ip = models.CharField(max_length=64, blank=True)
password = models.CharField(max_length=62, blank=True)
mac = models.CharField(max_length=17, blank=True)
description = models.fields.TextField(max_length=600, blank=True)
users = models.ManyToManyField(User,'users_device',through="UserMeta")
status = models.BooleanField(default=False)
def __str__(self):
return self.name
class UsersMeta(models.Model):
type_choices = [
("owner",'owner'),
('user','user'),
('admin','admin')
]
user = models.ForeignKey(User,on_delete=models.DO_NOTHING,related_name='UserMeta_devices')
device = models.ForeignKey(Device,models.CASCADE,related_name='UserMeta_device')
type = models.CharField(max_length=8,choices=type_choices)
token = models.UUIDField(default=uuid4,
editable=False,
unique=True)
join_time = models.DateTimeField(auto_now_add=True)
last_activate = models.DateTimeField(null=True,blank=True)
我需要对 设备 型号 depending 的特定权限访问 User模型在UserMeta模型中。
在 UserMeta 中,我有一些选择权限,例如:owner,admin,user,所以我要说这个User是否有权限OWNER,或者别的什么都行不行。
我不知道对不对,如果你知道请告诉我
更新:
class Device(ViewSet):
permission_classes = [permissions.IsAuthenticated]
########################################################
# Device #
########################################################
@extend_schema(
summary="Get All Devices of User",
request={
200: Serializer_Device,
},
responses={
200: Serializer_Device(many=True),
400: None,
},
)
def list(self, request) -> Response:
device = get_list_or_404(Device_Model, user=request.user)
serializer = Serializer_Device(device, many=True)
return Response(serializer.data, status=Status.HTTP_200_OK)
@extend_schema(
summary="Retrive a special device with the UUID token",
responses={
200: Serializer_Device,
404: None,
},
parameters=[
OpenApiParameter(
name="id",
description="Token of Device",
allow_blank=False,
type=OpenApiTypes.UUID,
location=OpenApiParameter.PATH,
)
],
)
def retrieve(self, request, pk) -> Union[Response, Http404]:
user = request.user
device = get_object_or_404(Device_Model, token=pk, user=user)
serializer = Serializer_Device(device)
return Response(serializer.data, status=Status.HTTP_200_OK)
@extend_schema(
summary="Full Update a Device",
request=Serializer_Device,
responses={
200: Serializer_Device,
404: None,
},
parameters=[
OpenApiParameter(
name="id",
description="Token of Device",
allow_blank=False,
type=OpenApiTypes.UUID,
location=OpenApiParameter.PATH,
)
],
)
def update(self, request, pk) -> Response:
device = get_object_or_404(Device_Model, token=pk, user=request.user)
serializer = Serializer_Device(
instance=device, data=request.data, context={"request": request}
)
if serializer.is_valid(raise_exception_validitor):
serializer.save()
return Response(serializer.data, status=status.HTTP_200_OK)
return Response(status=status.HTTP_400_BAD_REQUEST)
@extend_schema(
summary="Create a new device",
request=Serializer_Device,
responses={201: Serializer_Device, 400: dict},
)
def create(self, request) -> Union[Response, Http404]:
data = request.data
serializer = Serializer_Device(data=request.data, context={"request": request})
if serializer.is_valid(raise_exception_validitor):
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(status=status.HTTP_400_BAD_REQUEST)
@extend_schema(
summary="Delete Device with Token",
responses={
200: Serializer_Device,
204: None,
},
parameters=[
OpenApiParameter(
name="id",
description="Token of Device",
type=OpenApiTypes.UUID,
location=OpenApiParameter.PATH,
)
],
)
def destroy(self, request, pk) -> Union[Response, None]:
device = get_object_or_404(Device_Model, token=pk, user=request.user)
device.delete()
return Response(status=status.HTTP_204_NO_CONTENT)
@extend_schema(
summary="Filter Device With Tyep ",
responses={
200: Serializer_Device,
404: None,
},
parameters=[
OpenApiParameter(
name="type",
description="type of Device",
type=OpenApiTypes.STR,
location=OpenApiParameter.PATH,
)
],
)
@action(
detail=False,
methods=["GET"],
url_path=r"filter/(?P<type>\w+)",
url_name="filter_type",
)
def filter(self, request, type) -> Union[Response, Http404]:
user = request.user
device = get_list_or_404(Device_Model, type=type, user=user)
serializer = Serializer_Device(device, many=True)
return Response(serializer.data, status=Status.HTTP_200_OK)
########################################################
# Data #
########################################################
@extend_schema(
summary="get logs of the device",
responses={
200: Serializer_Device_Data,
404: None,
},
parameters=[
OpenApiParameter(
name="id",
description="Token of Device",
type=OpenApiTypes.UUID,
location=OpenApiParameter.PATH,
)
],
)
@action(detail=True, methods=["GET"], url_name="data")
def data(self, request, pk) -> Union[Response, Http404]:
user = request.user
token = pk
device = get_object_or_404(Device_Model, user=user, token=token)
data_instance = get_list_or_404(Data_Model, device=device)
serializer = Serializer_Device_Data(data_instance, many=True)
return Response(serializer.data, status=Status.HTTP_200_OK)
########################################################
# Command #
########################################################
@extend_schema(
summary="Get the last command",
responses={
200: Serializer_Command,
404: OpenApiTypes.OBJECT,
},
parameters=[
OpenApiParameter(
"id",
OpenApiTypes.UUID,
location=OpenApiParameter.PATH,
description="Toekn Device",
)
],
)
@action(detail=True, methods=["GET"], url_name="command")
def command(self, request, pk) -> Union[Response, Http404]: # Retrieve Command
data = request.data
status = get_object_or_404(Command_Model, device=pk)
serializer = Serializer_Command(status)
return Response(serializer.data, status=Status.HTTP_200_OK)
您可以像这样在 DRF 中定义您的自定义权限:
permissions.py:
from rest_framework.permissions import BasePermission
class IsOwner(BasePermission):
"""
Allows access only to owners
"""
def has_permission(self, request, view):
pk = request.GET.get('pk')
user_meta = UsersMeta.objects.filter(user=request.user, token=pk).first()
return True if user_meta and user_meta.type == "owner" else False
用法:
from rest_framework.views import APIView
from rest_framework.response import Response
from .permissions import IsOwner
class YourView(APIView):
permission_classes = (IsOwner,)
def get(self, request, format=None):
content = {
'status': 'owner users'
}
return Response(content)
我必须对Django 中的模型设置一些权限,因为我在DRF 中有一些操作,我需要知道用户是否有权限这样做。 我的模型:
class Device(models.Model):
type = models.ForeignKey(Type, on_delete=models.CASCADE)
name = models.fields.CharField(max_length=36)
ip = models.CharField(max_length=64, blank=True)
password = models.CharField(max_length=62, blank=True)
mac = models.CharField(max_length=17, blank=True)
description = models.fields.TextField(max_length=600, blank=True)
users = models.ManyToManyField(User,'users_device',through="UserMeta")
status = models.BooleanField(default=False)
def __str__(self):
return self.name
class UsersMeta(models.Model):
type_choices = [
("owner",'owner'),
('user','user'),
('admin','admin')
]
user = models.ForeignKey(User,on_delete=models.DO_NOTHING,related_name='UserMeta_devices')
device = models.ForeignKey(Device,models.CASCADE,related_name='UserMeta_device')
type = models.CharField(max_length=8,choices=type_choices)
token = models.UUIDField(default=uuid4,
editable=False,
unique=True)
join_time = models.DateTimeField(auto_now_add=True)
last_activate = models.DateTimeField(null=True,blank=True)
我需要对 设备 型号 depending 的特定权限访问 User模型在UserMeta模型中。 在 UserMeta 中,我有一些选择权限,例如:owner,admin,user,所以我要说这个User是否有权限OWNER,或者别的什么都行不行。
我不知道对不对,如果你知道请告诉我
更新:
class Device(ViewSet):
permission_classes = [permissions.IsAuthenticated]
########################################################
# Device #
########################################################
@extend_schema(
summary="Get All Devices of User",
request={
200: Serializer_Device,
},
responses={
200: Serializer_Device(many=True),
400: None,
},
)
def list(self, request) -> Response:
device = get_list_or_404(Device_Model, user=request.user)
serializer = Serializer_Device(device, many=True)
return Response(serializer.data, status=Status.HTTP_200_OK)
@extend_schema(
summary="Retrive a special device with the UUID token",
responses={
200: Serializer_Device,
404: None,
},
parameters=[
OpenApiParameter(
name="id",
description="Token of Device",
allow_blank=False,
type=OpenApiTypes.UUID,
location=OpenApiParameter.PATH,
)
],
)
def retrieve(self, request, pk) -> Union[Response, Http404]:
user = request.user
device = get_object_or_404(Device_Model, token=pk, user=user)
serializer = Serializer_Device(device)
return Response(serializer.data, status=Status.HTTP_200_OK)
@extend_schema(
summary="Full Update a Device",
request=Serializer_Device,
responses={
200: Serializer_Device,
404: None,
},
parameters=[
OpenApiParameter(
name="id",
description="Token of Device",
allow_blank=False,
type=OpenApiTypes.UUID,
location=OpenApiParameter.PATH,
)
],
)
def update(self, request, pk) -> Response:
device = get_object_or_404(Device_Model, token=pk, user=request.user)
serializer = Serializer_Device(
instance=device, data=request.data, context={"request": request}
)
if serializer.is_valid(raise_exception_validitor):
serializer.save()
return Response(serializer.data, status=status.HTTP_200_OK)
return Response(status=status.HTTP_400_BAD_REQUEST)
@extend_schema(
summary="Create a new device",
request=Serializer_Device,
responses={201: Serializer_Device, 400: dict},
)
def create(self, request) -> Union[Response, Http404]:
data = request.data
serializer = Serializer_Device(data=request.data, context={"request": request})
if serializer.is_valid(raise_exception_validitor):
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(status=status.HTTP_400_BAD_REQUEST)
@extend_schema(
summary="Delete Device with Token",
responses={
200: Serializer_Device,
204: None,
},
parameters=[
OpenApiParameter(
name="id",
description="Token of Device",
type=OpenApiTypes.UUID,
location=OpenApiParameter.PATH,
)
],
)
def destroy(self, request, pk) -> Union[Response, None]:
device = get_object_or_404(Device_Model, token=pk, user=request.user)
device.delete()
return Response(status=status.HTTP_204_NO_CONTENT)
@extend_schema(
summary="Filter Device With Tyep ",
responses={
200: Serializer_Device,
404: None,
},
parameters=[
OpenApiParameter(
name="type",
description="type of Device",
type=OpenApiTypes.STR,
location=OpenApiParameter.PATH,
)
],
)
@action(
detail=False,
methods=["GET"],
url_path=r"filter/(?P<type>\w+)",
url_name="filter_type",
)
def filter(self, request, type) -> Union[Response, Http404]:
user = request.user
device = get_list_or_404(Device_Model, type=type, user=user)
serializer = Serializer_Device(device, many=True)
return Response(serializer.data, status=Status.HTTP_200_OK)
########################################################
# Data #
########################################################
@extend_schema(
summary="get logs of the device",
responses={
200: Serializer_Device_Data,
404: None,
},
parameters=[
OpenApiParameter(
name="id",
description="Token of Device",
type=OpenApiTypes.UUID,
location=OpenApiParameter.PATH,
)
],
)
@action(detail=True, methods=["GET"], url_name="data")
def data(self, request, pk) -> Union[Response, Http404]:
user = request.user
token = pk
device = get_object_or_404(Device_Model, user=user, token=token)
data_instance = get_list_or_404(Data_Model, device=device)
serializer = Serializer_Device_Data(data_instance, many=True)
return Response(serializer.data, status=Status.HTTP_200_OK)
########################################################
# Command #
########################################################
@extend_schema(
summary="Get the last command",
responses={
200: Serializer_Command,
404: OpenApiTypes.OBJECT,
},
parameters=[
OpenApiParameter(
"id",
OpenApiTypes.UUID,
location=OpenApiParameter.PATH,
description="Toekn Device",
)
],
)
@action(detail=True, methods=["GET"], url_name="command")
def command(self, request, pk) -> Union[Response, Http404]: # Retrieve Command
data = request.data
status = get_object_or_404(Command_Model, device=pk)
serializer = Serializer_Command(status)
return Response(serializer.data, status=Status.HTTP_200_OK)
您可以像这样在 DRF 中定义您的自定义权限:
permissions.py:
from rest_framework.permissions import BasePermission
class IsOwner(BasePermission):
"""
Allows access only to owners
"""
def has_permission(self, request, view):
pk = request.GET.get('pk')
user_meta = UsersMeta.objects.filter(user=request.user, token=pk).first()
return True if user_meta and user_meta.type == "owner" else False
用法:
from rest_framework.views import APIView
from rest_framework.response import Response
from .permissions import IsOwner
class YourView(APIView):
permission_classes = (IsOwner,)
def get(self, request, format=None):
content = {
'status': 'owner users'
}
return Response(content)