Django Rest Framework: Without Model - django

I'm working on creating a RESTAPI using DRF(Django Rest Framework). API just receives the users twitter handle and returns his twitter data.
Here, I'm not using model here because it's not required.
Should I use a serializer here? If so why? Now I'm able to return the data without using a serializer.
Moreover, My API is not web-browsable. How should I make it web-browsable: which is one of the best features of DRF.
Edit:1
I'm using Functions in Views.
#api_view(['GET'])
#csrf_exempt
def getdetails(request):
call the twitter api
receive the data
return HttpResponse(JsonResponse( {'data': {'twitter_id':id,'tweets':count,'Followers':followers,'following':count_follow}}))
In the browser I'm just seeing JSON data like this.
{"data": {"twitter_id": 352525, "tweets": 121, "Followers": 1008, "following": 281}}

You can use Serializer for the result
class SampleSerializer(serializers.Serializer):
field1 = serializers.CharField()
field2 = serializers.IntegerField()
# ... other fields
Usage
my_data = {
"field1": "my sample",
"field2": 123456
}
my_serializer = SampleSerializer(data=my_data)
my_serializer.is_valid(True)
data = my_serializer.data
You'll get serialized data in data variable (you can use my_serializer.data directly)
Should I use a serializer here?
It's up to you, because if you wish to show the response JSON without any modification from the Twitter API, you can go without DRF serializer. And If you wish to do some formatting on the JSON, my answer will help you
My API is not web-browsable. How should I make it web-browsable?
Maybe you followed wrong procedure. Anyway we can't say more on this thing without seeing your code snippets
Update-1
from rest_framework.response import Response
#api_view(['GET'])
#csrf_exempt
def getdetails(request):
call the twitter api
twitter_api = get_response_from_twitter() # Json response
return Response(data=twitter_api)

Related

Nest model serializers in Django without using rest framework

I would like to know if it's possible to nest serializers without using the rest framework.
I was reading this question and I would like to do something similar but I am not allowed to use the rest framework.
Is it possible to serialize models with foreign keys using a similar approach (nesting) without using the rest framework?
At the moment I am serializing json like this:
data = serialize("json", myModelObject, fields=('id', 'foreignKeyField'), cls=DatetimeJSONEncoder)
And I would like to do something like this:
data = serialize("json", myModelObject, fields=('id', 'foreignKeyField.some_value'), cls=DatetimeJSONEncoder)
first make sure your view inherit from JSONResponseMixin
class JSONResponseMixin(object):
def render_to_json_response(self, context, **response_kwargs):
return JsonResponse(self.get_data(context), **response_kwargs)
def get_data(self, context):
return context
how about this :
Broaden your query values to include foreignKeyField.some_value
convert the queryset to list
return the json list as response for your ajax request
access your response as json array in ajax success
results = MyModel.objects.filte(my_filter).values("field_1",
"field_2",
"field_n",
"foreignKeyfield__field_11",
"foreignKeyfield__field_22")
results_list = json.dumps(results)
return JsonResponse(results_list)
it depends on your frontend technologie , try to output the reponse and parse with joy
let me know in the comments section if you need more details

Documenting a DRF GET endpoint with multiple responses using Swagger

I have a GET endpoint for a RESTful API I am creating using Django.
This endpoint reads three values from the URL's query string. A particular parameter in the query string has the potential to change the data (include extra fields and change the structure slightly) which is returned in the JSON response from this endpoint.
This endpoint is not tied directly to a single model. My view subclasses RetrieveAPIView, in the view, I override the get_object method and some logic is performed to query multiple models, make some decisions and return an ordered dictionary.
My problem is as follows:
I would like to document this endpoint using Swagger. I am using drf-yasg to generate my Swagger documentation. I have no serializers declared for this view; since I manually construct an ordered dictionary in get_object I don't see the purpose of declaring one. I'm not sure how to document my endpoint using drf-yasg.
I have discovered only one approach to document the endpoint, but it is quite ugly and bloats my code, and I'm wondering if there is a better approach.
By declaring an openapi.Response object, and supplying this object to the #swagger_auto_schema decorator Swagger displays the two possible responses, but describing the entire response really bloats my code. Here is an example if what currently works to document the endpoint:
class View(RetrieveAPIView):
http_method_names = ['get']
response_json = {
'Response if X query parameter is something': {
'key1': 'string',
'key3': {
'key4': 0,
'key5': 'string',
'key6': 'string'
}
},
'Response if X query parameter is something else': {
'key1': 'string',
'key2': 'string'
}
}
swagger_get_responses = openapi.Response(description='Description for the set of responses',
examples=response_json)
#swagger_auto_schema(responses={200: swagger_get_responses})
def get(self, request, *args, **kwargs):
return super().get(request, args, kwargs)
def get_object(self):
// Execute a method on a model that queries other models, performs some logic, and
// then returns an ordered dict which is then returned by this function.
Is there a better approach to this problem? Is there a better Django design pattern/feature of the Django framework or drf-yasg library that I can apply here that will help me handle multiple response bodies?

Django rest api validate data sent in the requests

I am trying to build a Django rest api to allow my clients to send requests with data, so that I can save them to a db. I have done that part but other than the format validation achieved through Serializers I also want check for data validation.... for example
UnitOfMeasureName = ["Each", "Grams", "Ounces", "Pounds", "Kilograms", "Metric Tons"]
UnitOfMeasureName should be one of the above in the list,
So if a user sends {..., 'UnitOfMeasureName': 'invalid_one', ...} in request data I want to send a bad request.
(This will pass the serializer as the type is string)
Any ideas please, If you need any clarification please ask in the comments. And thanks in advance.. :)
In your serializer class add a method to validate UnitOfMeasureName like following:
def validate_unitofmasurename(self, value):
UnitOfMeasureName = ["Each", "Grams", "Ounces", "Pounds", "Kilograms", "Metric Tons"]
if value in UnitOfMeasureName:
return True
else:
return ValidationError('Invalid masure name')

Post data as an array in Django Rest Framework

I'm implementing an API using Django Rest framework. I wonder Python can send POST params as an array like Ruby does?
For example:
POST /api/end_point/
params = { 'user_id': [1,2,3] }
# In controller, we get an array of user_id:
user_ids = params[:user_id] # [1,2,3]
There are a number of ways to deal with this in django-rest-framework, depending on what you are actually trying to do.
If you are planning on passing this data through POST data then you should use a Serializer. Using a serializer and django-rest-frameworks Serializer you can provide the POST data through json or through a form.
Serializer documentation: http://www.django-rest-framework.org/api-guide/serializers/
Serializer Field documentation: http://www.django-rest-framework.org/api-guide/fields/
Specifically you will want to look at the ListField.
It's not tested, but you will want something along the lines of:
from rest_framework import serializers
from rest_framework.decorators import api_view
class ItemSerializer(serializers.Serializer):
"""Your Custom Serializer"""
# Gets a list of Integers
user_ids = serializers.ListField(child=serializers.IntegerField())
#api_view(['POST'])
def item_list(request):
item_serializer = ItemSerializer(data=request.data)
item_serializer.is_valid(raise_exception=True)
user_ids = item_serializer.data['user_ids']
# etc ...

Django rest framework call a viewset programatically passing authentication headers from another view

I am trying to call an api made with Django Rest Framework drf. My case is that I want to call the api from another view get the response and display the data in a template. I have referred to this SO post, but could not make a successful call since my viewset requires authentication. Viewset works perfect if called using urls, the default way. Viewset is as below
class ViewSet(viewsets.ModelViewSet):
"""
API endpoint that allows Objects to be viewed or edited.
"""
permission_classes = (permissions.IsAuthenticated,)
queryset = Myclass.objects.all()
serializer_class = MyclassSerializer
....
....
return response(json)
On calling this api from another view the response that I get is a 401 page from drf api.
ipdb>view = Myview.as_view({'get':'list'}
ipdb>obj=view(request, *args, **kwargs)
ipdb> obj.data
{u'detail': u'Authentication credentials were not provided.'}
ipdb>obj.has_header('Authentication')
False
I tried passing Authentication headers also, but I dont know whether its the right way.
view = MyViewSet.as_view({'get':'list'},{'token':'token'})
This returned an error argument token is not accepted. And I tried
view = MyViewSet.as_view({'get':'list'},Authentication={'token':'token'})
But this Also returned me errors. How is it possible to call an api viewset from another view by passing auth params?
TIA