Django REST Framework - Logic and filters : better in Serializers or in ViewSets? - django-rest-framework

I am developing a Django REST Framework API. It has 13 models, 21 Serializers, and many related fields. Some serializers are nested and quite complex, to achieve an optimal result with a minimum number of front-end requests.
I am familiar with coding everything (excepted GET filters) in Serializers. For each request URL, I always create a basic ViewSet (I only mention the permission_class, serializer_class and queryset). I code in the ViewSet only the queryset filters for GET requests. All the additional logic (saving objects, calculating MethodFields, updating objects in multiple models for a unique request, sending notification emails...) is coded in the serializer.
Is it a good practice ? Or is there a more efficient way of sharing the logic between the serializer and the ViewSet ? Are there performance-improving opportunities ?

Related

Is it essential to send response data to dto when working with graphql?

Hi I am making api server with nestjs and graphql.
I have a question.
When the api server passes the response to the stack above.
Is it right to load the response into the dto?
If question number one is correct, what is the best way?
Or does the graphql schema type play the role of dto?
let me know thank you!
A DTO is an object that helps developers and consumers know what shape the data is going to be in as it goes "over the wire" (when the request or response is made). In GraphQL we use schemas to be our DTOs and follow the GraphQL Query Language spec so that our GraphQL server will know how to deserialize incoming requests and serialize outgoing ones in accordance to the shcemas we create. The only thing that matters in the end is that the data is the correct shape^, not that it's an instance of a class that we created for the sake of the server. With NestJS, it depends if you take the code-first or schema-first approach, but generally in the code-first approach it can be said that your GQL Schema is your DTO. From there, as long as the data looks like the DTO you should be fine.
^ excluding the use of nested schemas which can become problematic if you are trying to return raw JSON and nothing else

Documenting fields in Django Rest Framework

We're providing a public API that we use internally but also provide to our SaaS users as a feature. I have a Model, a ModelSerializer and a ModelViewSet. Everything is functional but it's blurting out the Model help_text for the description in the API documentation.
While this works for some fields, we would like to be a lot more explicit for API users, providing examples, not just explanations of guidance.
I realise I can redefine each field in a Serializer (with the same name, then just add a new help_text argument, but this is pretty boring work.
Can I provide (eg) a dictionary of field names and their text?
If not, how can I intercede in the documentation process to make something like that work?
Also, related, is there a way to provide a full example for each Viewset endpoint? Eg showing what is submitted and returned, like a lot of popular APIs do (Stripe as an example). Or am I asking too much from DRF's documentation generation? Should I handle this all externally?
To override help_text values coming from the models, you'll need to use your own schema generator subclass and override get_path_fields. There you'd be able to prioritize a mapping on the viewset (as you envision) over the model fields help_text values.
On adjusting the example generation - you could define a JSON language which just deals with raw JSON and illustrate the request side of things pretty easily, however, illustrating responses is difficult without really getting deep into the plumbing, as the default schema generated does not contain response structure data.

Organizing code related to regular Django and DRF

I have a web site powered by Django, and a respective Django REST Framework (DRF) Api for communicating data to outside world (say, Android). After doing a research, I came to a conclusion that REST framework's endpoints should not be used for rendering regular Django templates (used for rendering the website itself). So I have two sets of urls and views for the the same collection of ORM models. And the question is,
what is the best practice to name the DRF urls and regular urls, so that I do not confuse which one is used for web, and which one as endpoint for outside world
Should I define both DRF class-based views and regular views for rendering website in the same python file, or should I separate them?
To keeps things simple, imagine the project contains only one model.
class sms(models.Model):
# fields
class Meta:
managed = False
db_table = 'sms'
Now, I have two sets of views for this model (the DRF):
class SmsList(APIView):
renderer_classes = [JSONRenderer,TemplateHTMLRenderer]
# template_name = 'sms/incoming_list_paginator.html'
def get(self, request):
qs = SMS.objects.all()
serializer = SMSSerializer(qs, many=True)
return Response(serializer.data)
and regular view for rendering the respective webpage:
def get_sms(APIView):
qs = SMS.objects.all()
return render_to_response('test.html',
{'legal_entities_form':legal_entities_form},
context_instance=RequestContext(request))
Now, I have two urls which I would ideally like to name 'sms'. But I have to name them differently, like, sms and sms_rest. What is the best practice? Is it ok if I, say, add _rest suffix to all DRF-related urls ?

Trade offs between view and viewsets

I don't know why the documentation says:
That doesn't mean it's always the right approach to take. There's a similar set of trade-offs to consider as when using class-based views instead of function based views. Using viewsets is less explicit than building your views individually.
If I want to make a REST API (like in ruby-on-rail) I think viewsets is a good approach to take.
Can anyone explain more about it?
The main advantage of using viewsets over views is brevity. In the simple case, you can get more done with fewer lines of code.
The main disadvantage is that the simplifying assumptions made by viewsets might not always fit the problem space you are working in. As with class-based views in Django, if you try to apply the wrong pattern to a problem you can end up doing more work than you need to solve a problem.
My personal heuristic is that if I am doing the full set of CRUD operations on a model, I start with viewsets and go from there until I feel the convenience they provide is no longer worth the trouble I am incurring in that specific instance; if I am working with an API endpoint that doesn't map to any models, I'm far more likely to just use a view.
If I had the following models:
models.py
from django.db import models
class Gizmo(models.Model):
name = models.CharField(blank=True, null=False)
last_dusted = models.DateField(null=True)
class Sprocket(models.Model):
nom = models.CharField(blank=True, null=False)
last_dusted = models.DateField(null=True)
And I wanted to support the standard HTTP methods with their normal meanings, (namely GET and POST on the list view and GET, PUT, and DELETE on the detail view), I'd create a GizmoViewSet, a SprocketViewSet and call it a day.
Say I also wanted to offer API consumers the ability to dust off all of the gizmos at once. In that case, it would make sense to add a dust method to the GizmoViewSet using the #list_route decorator. Suppose that what I really wanted to do though was to offer a single endpoint where that API consumer could dust all the Gizmos and the Sprockets off at once. That doesn't really map very well to either viewset, so I'd add a one off view:
import datetime
from rest_framework.decorators import api_view
from rest_framework.response import Response
from my_app.models import Gizmo, Sprocket
# I used a function-based API view here, but a CBV APIView
# would work just as well. Matter of personal preference...
#api_view
def dust_everything(request):
today = datetime.date.today()
Gizmo.objects.all().update(last_dusted=today)
Sprocket.objects.all().update(last_dusted=today)
return Response({"status_of_dusting": "successful"})
So in that case I wouldn't be tearing out all my viewsets and replacing them with views; I'm adding an extra view to supplement the existing viewsets where it makes sense.

spring - difference between request.setAttribute and model.addAttribute?

can any one tell me the difference between request.setAttribute and model.addAttribute in spring web app?
The difference is, that Model is an abstraction. You could use Spring with servlets, portlets or other frontend technologies and Model attributes will always be available in your respective views.
HttpServletRequest on the other hand is an object specific for Servlets. Spring will also make request attributes available in your views, just like model attributes, so from a user perspective there is not much difference.
Another aspect is that models are more lightweight and more convenient to work with (e.g iterating over all attributes in a model map is easier than in a request).
Request V/s Model
where request could get attributes through getAttribute("") method. normally it is used for getting information from defined attributes and used inside the method for performing the different operations. So Basically Request used for input.
Just like Request, the model provides addAttribute("","") method, Through this model, we could make the object and storing data inside model object and deploying it on result Server Page.Basically it used in storing input data which is provide by us and storing for some time.

Resources