Improving the Public Posts API

Recall the services pattern example where we created a service to retrieve all the latest public posts? Now we shall reimplement it using the features provided by the DRF.

First, install DRF and add it to your INSTALLED_APPS. Then, mention your permission model in settings.py:

# Django Rest Framework settings 
REST_FRAMEWORK = { 
    # Allow unauthenticated access to public content 
    'DEFAULT_PERMISSION_CLASSES': [ 
        'rest_framework.permissions.AllowAny' 
    ] 
} 

Even though we are allowing unrestricted access (AllowAny) here, it is strongly recommended to choose the most restricted access policy to secure your API.

DRF allows us to choose from a wide variety of API access permission policies, such as allowing only authenticated users (IsAuthenticated) or allowing unauthenticated users read-only access (DjangoModelPermissionsOrAnonReadOnly), and more. More fine-grained object level permissions can also be defined.

Since we already have the Post model and model manager for public posts defined earlier, we shall create the Post serializer. Serializers are used for converting structured objects, such as model instances or QuerySets, into formats like JSON or XML that can be sent over the wire. They also perform the reverse function of deserialization, that is, parsing a JSON or XML back into a structured object.

Create a new file called viewschapter/serializers.py with the following content:

from rest_framework import serializers 
from posts import models 
 
 
class PostSerializer(serializers.ModelSerializer): 
    class Meta: 
        model = models.Post 
        fields = ("posted_by_id", "message") 

We are declaratively defining the serializers class by referring to the model class and the fields, which need to be serialized or deserialized. Note how this looks similar to defining a ModelForm.

This is intentional. Such as an HTML-based website needs forms to validate user input, a web API needs a deserializer to validate the data submitted to the API. Just as forms mapped to models are called ModelForms serializers mapped to models are called ModelSerializers.

Next, we define our API view in a separate file called viewschapter/apiviews.py:

from rest_framework.views import APIView 
from rest_framework.response import Response 
 
from posts import models 
from .serializers import PostSerializer 
 
 
class PublicPostList(APIView): 
    """ 
    Return the most recent public posts by all users 
    """ 
    def get(self, request): 
        msgs = models.Post.objects.public_posts()[:5] 
        data = PostSerializer(msgs, many=True).data 
        return Response(data) 

APIView class methods use different parameters and return types compared to Django's View class. It takes REST framework's Request instances, rather than Django's HttpRequest instances. It also returns REST framework's Response instances instead of Django's HttpResponse instances. However, it can be used just like a View class.

Finally, we wire this into our app's viewschapter/urls.py:

   path('api/public/', 
        apiviews.PublicPostList.as_view(), name="api_public"), 

Now, if you visit the http://127.0.0.1:8000/api/public/ API endpoint on your browser, you will see this awesome page:

Compare this to the earlier chapter's view that returned just a bare JSON string. We can see the name of this API endpoint and its description (from the APIView class docstring), the request headers, and the JSON payload itself (with syntax highlighting).

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.119.103.204