I have two questions about Django Rest Framework response message
1.
When use generics.ListCreateAPIView or RetrieveDestroyAPIView , usually return a resource
For example ,call /map/ with POST Method
The result will like a object :
{
"x_axis": "23",
"y_axis": "25",
"map_id": 1,
}
I want to know can I edit this message to custom like below?
{"Success":"msg blablabla"}
2.
When I use serializers.ValidationError ,
I can write my custom message
if I use raise serializers.ValidationError("map_id does not exist")
The response message will be
{"map_id":["map_id does not exist"]}
Can I edit this part to custom like below?
{"FAIL":"map_id does not exist"}
I want to know this because front-end don't want this format,
They like :
{"Success":"msg blablabla"}
{"Fail":"msg blablabla"}
{"USERNAME_DUPLICATE":1001}
{"FIELD_REQUIRED":1002}
So they can be more convenient to tell user the operate error cause ?
1 Overwrite the create method on the view and put something like this:
def create(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
self.perform_create(serializer)
headers = self.get_success_headers(serializer.data)
return Response({"Success": "msb blablabla"}, status=status.HTTP_201_CREATED, headers=headers)
2 In the code above, change raise_exception to False and return whatever you want if the serializer is not valid. i.e.:
def create(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
if not serializer.is_valid(raise_exception=False):
return Response({"Fail": "blablal", status=status.HTTP_400_BAD_REQUEST)
self.perform_create(serializer)
headers = self.get_success_headers(serializer.data)
return Response({"Success": "msb blablabla"}, status=status.HTTP_201_CREATED, headers=headers)
You are using CBV so you'll be able to create your custom generic classes that extends DRF's classes, and DRY
however, I'd say that you shouldn't add "success" or "fail" in your responses... if the http code is 2xx the user will know it was OK, 4xx when the request has a problem and 5xx when there was a error on your code (or the server), you don't need to repeat that information on the body of your response, just use the HTTP status codes
Hope this helps
Related
My api was set to api/barrel/details/<int:pk> originally but i want to make the delete function into api/barrel (which only have get and post function) without parsing the pk
class BarrelAPIView(APIView):
def get(self,request):
barrel = Barrel.objects.all() #queryset
serializer = BarrelSerializer(barrel, many=True)
return Response(serializer.data)
def post(self,request):
serializer = BarrelSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
def delete(self,request):
try:
data = request.data
Barrel.objects.filter(code=data['code']).delete()
return Response(status=status.HTTP_204_NO_CONTENT)
except Exception as error:
return Response( status=status.HTTP_400_BAD_REQUEST)
It can be done on postman by parsing the 'code'. but when i try on restframework default api browser the delete button showed up but nothing happens after that
You should check out:
https://www.django-rest-framework.org/api-guide/generic-views/#mixins
in the long run it will make your life easier..
The url could have any structure you like.
I would also suggest to refer to:
Two scoops of Django that introduce you to various tips, tricks, patterns, code snippets, and techniques
I am using Django Rest Framework to upload a file
My view file looks like this:
class FileViewSet(viewsets.ModelViewSet):
queryset = Files.objects.all()
serializer_class = FilesSerializer
#+++++++++++++++++++++++++++++++++++++
parser_classes = (MultiPartParser, FormParser)
def post(self, request, *args, **kwargs):
serializer = FilesSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=HTTP_201_CREATED)
else:
return Response(serializer.error, status=HTTP_400_BAD_REQUEST)
My view works well with file upload even if there is no bottom part of the comment.
So why should I use the code under the comment?
I used the translator.
Please understand if there is a mistake.
Your code is working without the post function because ModelViewSet class(i.e the one you inherited in your FileViewSet) already has implementations of various actions like list(),create(), retrieve(), update() etc.
So when you are hitting post request for uploading the file, create() action gets called automatically and will save the file by taking values provided by you in class variables like serializer_class,parser_classes etc.
Read more about ModelViewSet:
Im trying to perform partial update in DRF using angular $http.
In my DRF model viewset i override the partial_update function (server side).
class AnimalTreatmentViewSet(viewsets.ModelViewSet):
queryset = MyObject.objects.all()
serializer_class = MyObjectSerializer
def create(self, request):
# It works with $http.post()
pass
def update(self, request, pk=None):
# It works with $http.put()
pass
def list(self, request):
# It works with $http.get()
pass
def partial_update(self, request, pk=None):
# This one wont work with $http.patch()
instance = self.get_object()
serializer = self.serializer_class(instance, data=request.data, partial=True)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_200_OK)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
In the client side angular handle the user request.
$http.patch('/api/my_viewset_url/1', data);
But i got this response Method Not Allowed (PATCH): /api/my_viewset_url/1
When using $http.get() request with DRF model viewset list(self, request) it works well for getting a list same goes for $http.post() with def create(self, request) for creating object and $http.put() with def update(self, request) for updating object.
What's wrong? or what is the correct http verb for partial_update in DRF model viewset
It seems like the URL is missing a trailing slash.
Related documentation:
By default the URLs created by SimpleRouter/DefaultRouter are appended with a
trailing slash. This behavior can be modified by setting the trailing_slash argument to False when instantiating the router. For example:
router = routers.DefaultRouter(trailing_slash=False)
I am newbie in Django and Django REST Framework. I have the following serializer class which I am using to upload a file along other information. But, while I run the API endpoint with uploaded file, the result is something like this:
HTTP 415 Unsupported Media Type
Allow: POST, OPTIONS
Content-Type: application/json
Vary: Accept
{
"detail": "Unsupported media type \"multipart/form-data; boundary=----WebKitFormBoundaryybZ07gjZAqvcsZw3\" in request."
}
I tried hard by googling to solve this issue, but cannot come out in a solution, so here is my serializer and API views.
Serializer:
class ExampleSerializer(serializers.Serializer):
example_id = serializers.IntegerField()
description = serializers.CharField(allow_blank=True)
example_file = serializers.FileField(allow_empty_file=True)
def create_requirement_line(self):
request = self.context['request']
requirement_line = ExampleService().example_method(
example_id=self.validated_data['example_id'],
description=self.validated_data['description'],
example_file=self.validated_data['example_file']
)
return requirement_line
View:
class RequirementLineAPIView(BaseCreateAPIView):
serializer_class = ExampleSerializer
parser_classes = (FormParser,)
def post(self, request, format=None,*args, **kwargs):
serializer = self.get_serializer(data=request.data)
if serializer.is_valid():
try:
example_variable = serializer.example_method()
return Response(example_variable, status=status.HTTP_200_OK)
except ValidationError as e:
return Response(e.message, status=status.HTTP_400_BAD_REQUEST)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
You should use the MultiPartParser instead of the FormParser if you're sending multipart/form-data.
Raised if there are no parsers that can handle the content type of the request data when accessing request.DATA or request.FILES.
check Django REST Framework2 documentation
import suitable parser
from rest_framework.parsers import MultiPartParser, FormParser, JSONParser
class SampleView(APIView):
parser_classes = (MultiPartParser,FormParser,JSONParser)
Try Using FileField parser
Using Parsers in django rest
I am using the Django REST framework in order to implement a game server for an android game. I have written a class, that is derived from GenericAPIView to handle a specific Http Post request. I want the request to return a list of some objects, that were previously queried from the database.
My code looks like this:
class NewGameView(GenericAPIView):
serializer_class=NewGameRequestSerializer
def post(self, request, format=None):
serializer = NewGameRequestSerializer(data=request.DATA)
if serializer.is_valid():
req=serializer.save()
mygamedata=...; # request game data objects
serializer = MyGameDataSerializer(mygamedata, many=True)
return Response(serializer.data,status=status.HTTP_201_CREATED)
else:
return Response(status=status.HTTP_400_BAD_REQUEST)
When I access this view via curl, everything works as expected. However, when I submit using the Django generated "browsable api" form, I am receiving a
'ListSerializer' object is not iterable
error during "template rendering". If I derive my class from APIView instead, the error does not occur, but Django will not display the forms anymore (for whatever reason).
Can anyone explain what is going on?
Thanks
You can just return a dictionary with the data you need.
class NewGameView(GenericAPIView):
serializer_class=NewGameRequestSerializer
def post(self, request, format=None):
serializer = NewGameRequestSerializer(data=request.DATA)
if serializer.is_valid():
req=serializer.save()
mygamedata=...; # request game data objects
data = {'game_name': mygame_object.name}
return Response(data,status=status.HTTP_201_CREATED)