Post data as an array in Django Rest Framework - django

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 ...

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

Accessing Django 3 TextChoices via an exposed API endpoint?

I am using Django 3.0.4 with Django REST Framework 3.11.0 where I have a models.py like:
from django.db import models
from model_utils.models import TimeStampedModel
class SampleModel(TimeStampedModel):
class Options(models.TextChoices):
FOO = "A"
BAR = "B"
BAZ = "C"
name = models.CharField(default="", max_length=512)
options = models.CharField(
max_length=2,
choices=Options.choices,
default=Options.FOO
)
I would like to be able to create an API endpoint to return a list of my TextChoices as a tuple. I have a React frontend where I want to create a <select> dropdown with my list of choices. If I can access the list of TextChoices via an API endpoint, I should be good to go.
path("api/sample/choices/", views.SampleChoicesListView.as_view(), name="sample_choices")
I'm not sure what my views.py needs to look like to make this work...
class SampleChoicesListView(generics.ListAPIView):
pass
Return the SampleModel.Options.choices as Response in an APIView
from rest_framework.views import APIView
from rest_framework.response import Response
# other required imports
class SampleChoicesListView(APIView):
def get(self, request):
# SampleModel.Options.choices would return
# [('A', 'Foo'), ('B', 'Bar'), ('C', 'Baz')]
choices = SampleModel.Options.choices
# format it into dictionary
# choices = {choice[0]: choice[1] for choice in SampleModel.Options.choices}
return Response(choices)
Add urlpattern to api urls
path("options/", views.SampleChoicesListView.as_view(), name="options"),
List structure:
Dictionary structure:
It may be cleaner to instead make an OPTIONS request to the SampleModel endpoint which should enumerate the valid options for that field, and also saves you creating a separate endpoint just to list the options. DRF should handle this all for you.

Django Rest Framework: Without Model

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)

Django: return query result as api

I'm trying to build an API server using Django. I have a few tables and I need to run queries based on the parameters passed in by url:
http://server.com/api/request/p1=123&p2=321...
and the server would extract p1 and p2 from url and run queries using them, and then return the result in json or xml.
I have tried Tastypie, and it's very easy to set up for retrieving data from one model. But my case is a bit complicated than that, and sometimes I need to run spatial queries. So if I could run the query and return result as json/xml, it would be great!
Very new to the backend technology, any help for a start point is appreciated!
Thanks!
[Edit]
Just want to make my case clearer. Say I ran a raw query using qs = cursor.execute(sql), etc., and I want to return that result as json/xml to a api call. Can I do that with either Tastypie or Rest Framework? Or can I do it without any help from 3rd party framework?
Here's a view I use return json, you should be able to adapt it pretty easy:
import json
from django.http import HttpResponse
from django.template.defaultfilters import slugify
from .models import *
def response_times(request):
response_data = {} #Create an empty dictionary
websites = Website.objects.all() #Query your models
for site in websites:
key = slugify(site.name)
response_data[key] = {}
history = History.objects.filter(website=site)[:60]
response_data[key]['response_times'] = []
for response in history:
response_data[key]['response_times'].append({'time': str(response.time), 'timestamp': response.added.strftime('%s')})
return HttpResponse(json.dumps(response_data), content_type="application/json")
It seems you have in the result QuerySet of some Model instances. So you could specify serializer to work with your model and use it to serialize from model instances to native python data using Rest Framework. Look here for details.

How to generate form in browsable API without using a serializer_class?

Lets assume I've an API that expects a couple GET args: 'foo' and 'bar'. And I haven't defined serializer_class due to it isn't tied to any specific model:
from rest_framework.generics import GenericAPIView
from rest_framework.response import Response
class myAPI(GenericAPIView):
def get(self, request, format=None):
foo = request.GET.get('foo')
bar = request.GET.get('bar')
# do something with foo & bar
return Response({'fooplusbar': _something(foo,bar)})
Is there any way to tell to djangorestframework to build the form in this kind of situation?
The Django REST Framework only supports forms out of the box for POST, PUT and PATCH requests.
In those cases, the form is generated from the serializer. There is nothing wrong with defining a serializer which does not return Model objects, nor with using the serializer for form display only, and write e.g. a custom POST handler which does not make use of it. But for Django REST Framework to show a form, you must define a serializer.
It would be quite possible to add support for proper GET forms, but you'd need to extend rest_framework.renderers.BrowsableAPIRenderer.render to add the new form to the context, and write your own templates in rest_framework/api.html.