Closed noobmaster19 closed 3 years ago
It seems that the @list_route
has been deprecated , wondering if this package supports @action
as well
@neowenshun Can you share the serializer you use with this view at the moment you get the error to allow me reproduce it on my side ?
For me it seems that you just forgot the Meta model in you serializer, but we will see with your code
class Meta:
model = SalesProject
The line that create your issue is this one, it's a security but it seems that in your console output you don't get the explanation message. We will control that.
Thanks , appreciate the quick reply , here is the serializer for the SalesProject
class SalesProjectDetailSerializer(serializers.ModelSerializer):
items = ProjectItemDetailSerializer(many=True, read_only=True)
notations = SalesNotationProjectSerializer(many=True, read_only=True)
....
class Meta:
model = SalesProject
fields = '__all__'
depth = 2
The way i structure my project might be different from most people ? Im unsure as there isn't really a generally accepted practice (or so i think) . I have a detail serializer which helps me to serialize all the data for my detail page . It is comprised on multiple serializer methods and serializerfields so that i can customize the depth and fields .
The def getexternalcustomers(self, request, pk=None):
is one of the methods of the overall SalesProjectViewSet , which helps me to get data from a related model , CustomerInformation
, for a certain form that im using for the detail page.
Here is the serializers that are involved for the custom action def getexternalcustomers(self, request, pk=None):
class ProjectCustomerSerializer(serializers.ModelSerializer):
class Meta:
model = CustomerInformation
fields = '__all__'
depth = 1
I realized that the problem only arises when im trying to access a url that was defined by @action[...]
@neowenshun Ok, thanks for the details.
I think that effectivelly the way you get the serializer is the problem, dry-rest-permissions
based his logic on the DRF architecture and more particulary on the usage of the get_serializer_class()
method inherited by ModelViewSet
Since your action getexternalcustomers
hardcode the usage of a specific serializer class without using the get_serializer_class()
the package does not find the serializer class you want to use.
First solution
@action(detail=True, methods=['GET'], name='getexternalcustomers')
def getexternalcustomers(self, request, pk=None):
queryset = CustomerInformation.objects.exclude(salesproject__in=pk)
self.serializer_class = ProjectCustomerSerializer
serializer = self.get_serializer(queryset, many=True)
return Response(serializer.data)
With this solution you keep the DRF architecture, you should be compatible with most of the package using the DRF architecture and in bonus you add the context to the serializer that you lacked until now and could be a problem (https://github.com/FJNR-inc/dry-rest-permissions#definition-1)
A serializer with this field MUST have the request accessible via the serializer's context. By default DRF passes the request to all serializers that is creates. However, if you create a serializer yourself you will have to add the request manually like this:
serializer = TestSerializer(data=request.data, context={'request': request})
If this code does not work try to add logic in your get_serializer_class() method directy
Second solution
As described here
If you want to define DRYPermissions for only some subpart of your view you can override the get_permissions function on the view like this:
def get_permissions(self):
if self.request.method == 'GET' or self.request.method == 'PUT':
return [DRYPermissions(),]
return []
Hms thank you for the very detailed feedback. I have taken your feedback and utilized it within my code and it working . However , i did not use self.serializer_class = ProjectCustomerSerializer
as there was an error. It would seem its because i overrode the get_serializer_class
method . By specifying the action url there instead i have gotten it to work , thank you so much for your help !
I might have more questions if you wouldnt mind me asking(The correct way to utilize both this package and django's default permissions package). Should i open a new thread for that?
@neowenshun No problem, all the pleasure is for me. It's always interesting to see the usage that other developers have with this package. It allows us to enhance it and learn good new ideas for our own projects!
Feel free to create new tickets for your others questions in order to keep it clear for future developers that search answers. I will make sure to keep all of your questions in considerations to enhance the documentation.
Here is the full error trace back.
The following is my code:
Here is my model:
The problem arises when i try to access a route that has
@action(...)
i believe