16:30 pm
PragetX
PPP
Bulk Permission Update.
Bulk Permission retrieval based on designation Id for all pages.

And Bulk Update Permission Using following schema.

- This will create the permissions if doesn’t exists and update if permission exists.
Had to use a bunch of Serializers. I was never this great at it in Django. Main thing that pushed me to make it good was Swagger. A nice way to check apis in OpenAPI format.
class CustomPermissionUpdateSerializer(serializers.ModelSerializer):
class Meta:
model = Permission
fields = ["can_view", "can_add", "can_edit", "can_delete"]
class PagePermissionsSerializer(serializers.ModelSerializer):
permission = serializers.SerializerMethodField()
class Meta:
model = Page
fields = ["id", "route_name", "priority", "permission"]
def get_permission(self, obj):
permission_obj = Permission.objects.filter(
route=obj, designation=self.context["designation"]
).first()
permission_obj_serializer = CustomPermissionUpdateSerializer(permission_obj)
return permission_obj_serializer.data
class PagePermissionUpdateSerializer(serializers.Serializer):
page_id = serializers.PrimaryKeyRelatedField(queryset=Page.objects.all())
permission = CustomPermissionUpdateSerializer()
def update(self, instance, validated_data):
permission_data = validated_data.pop("permission")
permission = instance.permission
instance.route = validated_data.get("page_id", instance.page_id)
instance.save()
for attr, value in permission_data.items():
setattr(permission, attr, value)
permission.save()
return instance
class DesignationPagePermissionSerializer(serializers.ModelSerializer):
pages = serializers.SerializerMethodField()
id = serializers.IntegerField(read_only=True)
designation_name = serializers.CharField(read_only=True)
description = serializers.CharField(read_only=True)
is_active = serializers.BooleanField(read_only=True)
created_at = serializers.DateTimeField(read_only=True)
updated_at = serializers.DateTimeField(read_only=True)
class Meta:
model = Designation
fields = [
"id",
"designation_name",
"description",
"is_active",
"created_at",
"updated_at",
"pages",
]
def get_pages(self, obj):
pages = Page.objects.all()
return PagePermissionsSerializer(
pages, many=True, context={"designation": obj}
).data
class DesignationPagePermissionUpdateSerializer(serializers.ModelSerializer):
pages = serializers.ListField(child=PagePermissionUpdateSerializer())
class Meta:
model = Designation
fields = ["pages"]
def update(self, instance, validated_data):
pages_data = validated_data.pop("pages", [])
updated_page_permission = []
for page_data in pages_data:
page = page_data["page_id"]
original_permission = Permission.objects.filter(
route=page, designation=instance
).first()
updated_permission_data = page_data["permission"]
updated_permission_data["route"] = page.id
updated_permission_data["designation"] = instance.id
if original_permission:
updated_permission = PermissionCreateUpdateSerializer(
original_permission, data=updated_permission_data
)
if updated_permission.is_valid():
updated_permission.save()
updated_page_permission.append(
{"page": page, "permission": updated_permission}
)
else:
raise serializers.ValidationError(updated_permission.errors)
else:
updated_permission = PermissionCreateUpdateSerializer(
data=updated_permission_data
)
if updated_permission.is_valid():
updated_permission.save()
updated_page_permission.append(
{"page": page, "permission": updated_permission}
)
instance = DesignationPagePermissionSerializer(instance).data
return instanceAnd then simple ModelViewSet
class DesignationBulkPermissionApi(ModelViewSet):
queryset = Designation.objects.all()
serializer_class = DesignationPagePermissionSerializer
permission_classes = [IsAdminUser]
def get_serializer_class(self):
if self.action in ["create", "update"]:
return DesignationPagePermissionUpdateSerializer
return self.serializer_class
@swagger_auto_schema(
# request_body=DesignationPagePermissionSerializer,
operation_description="Designation Bulk Permission",
)
def retrieve(self, request, *args, **kwargs):
designation_obj = Designation.objects.get(id=kwargs.get("pk"))
serializer = self.serializer_class(designation_obj)
response = {
"data": serializer.data,
"status": status.HTTP_200_OK,
}
return Response(response, status=status.HTTP_200_OK)
@swagger_auto_schema(
request_body=DesignationPagePermissionUpdateSerializer,
operation_description="Designation Bulk Permission",
)
def update(self, request, *args, **kwargs):
designation_obj = Designation.objects.get(id=kwargs.get("pk"))
serializer = self.get_serializer(designation_obj, data=request.data)
if serializer.is_valid(raise_exception=True):
serializer.update(designation_obj, serializer.validated_data)
response = {
"message": "Permission Updated",
"status": status.HTTP_200_OK,
}
return Response(response, status=status.HTTP_200_OK)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)Prevent Deletion of contents if they are foreign key in other objects.
Similar Logic as 11th March, Monday, 2024 for any models Category, Sub category, company, product, route, shop, designation, user.
If they are foreignkey in any other obeject. Prevent deletion of it.
For all model viewset same logic implemented.
def destroy(self, request, *args, **kwargs):
data = self.get_serializer(self.get_object(request)).data
obj_exists = Model.objects.filter(some_field=data['id']).exists()
# e.g.
# shop_exists = Shop.objects.filter(salesman=data["id"]).exists()
return (
error_response_child_exists
if obj_exists # or shop_exists or order_exists
else super().destroy(request, *args, **kwargs)
)Links : Tags : Year : 2024 Month : March 24, March Date : 13th March, Wednesday, 2024, 13th March Category : Daily