Pagination on Django Rest Framework when the data does not come from a model from the database - django-rest-framework

I'm trying to create an endpoint who returns the values from an Enum, but I need to make it with pagination because the UI library we use was designed to received exactly the same format that Django Rest Framework return when we read from a database.
The problem is that I cannot make the pagination to work. No matter which base class I use (ApiView, ListView, etc), the Response return doesn't has the count, next, previous and results fields (in results is where the real json should be).
I tried to overwrite pagination with pagination_class on the view class, and also creating a custom pagination class based on PageNumberPagination, but nothing.
Also, I tried to create a custom get_paginated_response method on my custom pagination class, but when I debug it looks like the method is not called.
What I'm doing wrong? I imagine it should be a way to tell DRF "take this data, even if is not from a model, and return that as a paginated list of fields"

When this happened to me in the past, I just called paginate_queryset with the enum and the request. Then, you need to return the response of get_paginated_response(page). So, something like this:
class SampleViewSet(views.ViewSet):
def list(self, request):
values = [e.value for e in MyEnum]
paginator = YourPaginationClass()
page = paginator.paginate_queryset(values, request)
if page is not None:
return paginator.get_paginated_response(page)
return Response(data)

Related

is creating serializer mandatory for each View in django rest frame work

I am working on app where I didnt use serializer in one view I just want to ask am I doing something wrong.
I am getting a committee id in the url and in the body I am getting the usr_id whos status I want to change if someone sends a post request to this end point.
This is my url
path('committee/<int:id>/accept-request/', RequestAcceptView.as_view(), name="accept-request"),
this is my view.py
class RequestAcceptView(APIView):
def post(self, request, id):
user_id = request.data['user']
print("iddddd",user_id )
try :
approve_request = Member.objects.filter(
Q (com=Committee.objects.get(id=id))
).update(mem_status="fully_approved")
return Response(SuccessResponse(msg="Request accepted"))
except:
return Response(ErrorResponse(msg="invalid))
I want to know I am not using serializer here for any purpose, is it fine? should I remove serializer file?
No, it is not when you are using ApiView. Generic and ModelView requires them. You should also think about if you want to have auto generated documentation you need the serializer and it will also perform validation (because you are not using the id field, but request.data.
If request.data and I'd are the same, then you might want to delete the serializer

how to get validated data from serializers to views in django rest framework

I am returning some data from def create method in seriaizers.py file I want to acccess that data in views.py I dont know how to get it.
serilizers.py
def create(self, validated_data):
//returning something
return validated_data
views.py
if serializer.is_valid():
serializer.save()
//I want to return that validated_data here so how to get it here here
Response(validated_data)
To get the validated data, use serializer.validated_data. See the Deserializing Objects section of the manual.
Also, I want to point out a potential footgun here: you're supposed to return a model instance, from the create() method, rather than the validated data.

GET should be for detail, but POST should not for an action method in Django-Rest-Framework

In my application there are elements called DemanderCollection which are rows which contain important metadata about collections of features called Demander
I have a ViewSet which I use to return the Demander objects associated with a specific DemanderCollection in my database encoded as a GeoJSON (a specific kind of JSON used for exchanging geographic data), and it is bound to a special action method called geojson:
class DemanderCollectionViewSet(
mixins.CreateModelMixin,
mixins.RetrieveModelMixin,
mixins.ListModelMixin,
viewsets.GenericViewSet
):
queryset = DemanderCollection.objects.all()
serializer_class = DemanderCollectionSerializer
#action(detail=True, methods=["get"])
def geojson(self, request, *args, **kwargs):
demanders = Demander.objects.filter(demandercollection=self.get_object())
return Response(serialize('geojson', demanders, geometry_field='geom', fields=('name',)))
This special action method is set to detail=True because I want to return only one DemanderCollection worth of Demander features.
I would also like to allow that users can post a new DemanderCollection simply by posting a GeoJSON to the same endpoint (with validation to make sure the properties/columns are valid).
But the problem is that now the geojson method is already defined as being detail=True, and so I cannot post to the endpoint
.../api/demandercollections/geojson
because it is expecting there to be an id in between, like
.../api/demandercollections/0/geojson
Can I make the geojson endpoint ignore the detail=True only when making a POST request?

How to get the id attribute when I'm inside the perform_validation method of the serializer

When I'm inside the perform_validation method of a given serializer I need access to the "id" of the model I've requested (at my RetrieveUpdateDestroy endpoint)
def perform_validation(self, attrs):
name = attrs['name']
guid = attrs['id'] #broken :(
What is the best way to get this when I'm inside the validation method?
Use the serializer context, that's provided by the generic view.
See here for what context is populated by default: https://github.com/tomchristie/django-rest-framework/blob/master/rest_framework/generics.py#L83
You should be able to do something like this: self.context['view'].kwargs['pk']

Django: is there a generic handler to insert a POST object directly into the database?

Django: is there a generic handler to insert a POST object directly into the database? I find myself writing a lot of handlers that look like this.
def ajax_storeObject(request):
if request.method == 'POST':
Object(
field1 = request.POST["field1"],
field2 = request.POST["field2"],
field3 = request.POST["field3"],
field4 = request.POST["field4"],
).save()
return HttpResponse(json.dumps({"status":"Success"}), mimetype="application/json")
return HttpResponse(json.dumps({"status":"Failed"}), mimetype="application/json")
It seems like there could be a one-line generic view to take care of this kind of thing. Does such a view exist?
Edit: BTW, I'm comfortable with model forms, but the use case I'm looking at here is more narrow: RESTful AJAX calls that aren't based on standard forms (e.g. the user manipulates an object on the page, and a REST call is sent to notify the server.).
There is nothing about forms that requires you to actually draw a form. ModelForms are the right thing to use if you're not going to go with piston or tastypie or something like that.
Put this in your page:
https://docs.djangoproject.com/en/dev/ref/contrib/csrf/#ajax
class ObjectAjaxForm(forms.ModelForm):
class Meta:
model = Object
fields = ("field1", "field2", "field3", "field4")
#or, if you don't want the "free" csrf protection
##csrf_exempt
def ajax_store_object(request):
#request.POST can be substituted with any dictionary/dictionary like object
form = ObjectAjaxForm(request.POST)
if form.is_valid():
form.save()
return HttpResponse(json.dumps({"status":"Success"}), mimetype="application/json")
else:
return HttpResponse(json.dumps({"status":"Failed"}), mimetype="application/json")
have you looked at model forms?
As far as I know, there is no generic Ajax view, but perhaps you are looking for this?
Object(**request.POST).create()
Of course, you need to make sure request.POST doesn't contain anything you don't want to put in the model (like a "submit" field).

Resources