HelloGitHub- dream chasers

Django-rest-framework provides the Serializer, Viewset, Router, and other convenience tools for the django-Rest-Framework. You can develop RESTful apis very quickly.

Comment is another resource, and we also use the above tools to complete the interface development of Comment resources.

The first step is to design the URL of the comment API. According to the design specification of the RESTful API, the URL of the comment resource is designed as: /comments/

There are two operations for comment resources: obtaining the comment list under an article and creating a comment. Therefore, the corresponding HTTP requests and actions are as follows:

The HTTP request Action URL
GET list_comments /posts/:id/comments/
POST create /comments/

The post comment list API uses custom actions under the view set of the/POST/interface; The comment interface uses the standard CREATE Action and needs to define a separate set of views.

You then need a serializer that serializes the comment resource (when the comment is fetched) and deserializes it (when the comment is created). With the basics of writing article serializers, comment serializers are a matter of following suit.

comments/serializers.py

from rest_framework import serializers
from .models import Comment

 class CommentSerializer(serializers.ModelSerializer):  class Meta:  model = Comment  fields = [  "name". "email". "url". "text". "created_time". "post". ]  read_only_fields = [  "created_time". ]  extra_kwargs = {"post": {"write_only": True}} Copy the code

Note here that we have added read_only_fields and extra_kwargs declarations to Meta.

Read_only_fields Specifies a list of read-only fields. Because created_time is automatically generated and used to record the time when comments are posted, it is declared read-only and cannot be modified through the interface.

Extra_kwargs specifies additional parameters to be passed to each serialized field. Here, the POST serialized field is declared as a write-only field by passing the write_only keyword parameter, so that the value of the POST field is only needed to create a comment. In the returned resource, the POST field does not appear.

To implement the interface for creating comments, create a set of views for the comments:

comments/views.py

from rest_framework import mixins, viewsets
from .models import Comment
from .serializers import CommentSerializer
 class CommentViewSet(mixins.CreateModelMixin, viewsets.GenericViewSet):  serializer_class = CommentSerializer   def get_queryset(self):  return Comment.objects.all() Copy the code

The view set is very simple, and when mixed with CreateModelMixin, the view set implements the standard Create Action. In fact, the create Action method implementation is very simple, let’s learn CreateModelMixin source code implementation.

class CreateModelMixin:
    "" "    Create a model instance.
"" "
    def create(self, request, *args, **kwargs):
 serializer = self.get_serializer(data=request.data)  serializer.is_valid(raise_exception=True)  self.perform_create(serializer)  headers = self.get_success_headers(serializer.data)  return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)   def perform_create(self, serializer):  serializer.save()   def get_success_headers(self, data):  try:  return {'Location': str(data[api_settings.URL_FIELD_NAME])}  except (TypeError, KeyError):  return {} Copy the code

The core logic is in the CREATE method: first fetch the serializer bound to user-submitted data for deserialization. The is_valid method is then called to verify that the data is valid. If not, an exception (raise_Exception =True) is raised. Otherwise, serialized save logic is executed to store the comment data into the database, and the response is returned.

Then register the CommentViewSet view set in the router:

router.register(r"comments", comments.views.CommentViewSet, basename="comment")
Copy the code

Enter the API interaction background, you can see that the URL of the comments interface is listed on the home page. After clicking/Comments /, you can see a comment form, where you can submit comment data and interact with the interface that creates comments.


Next, implement the interface to get the list of comments. Normally, we only get the list of comments under a blog post, so our API is designed to be /posts/:id/comments/. This interface is very semantic and conforms to the design specifications of RESTful apis.

Since the interface is under /posts/, we’ll add a custom action to PostViewSet to implement this. Let’s look at the code:

blog/views.py

class PostViewSet(
 mixins.ListModelMixin, mixins.RetrieveModelMixin, viewsets.GenericViewSet ):
 #...   @action(  methods=["GET"]. detail=True. url_path="comments". url_name="comment". pagination_class=LimitOffsetPagination,  serializer_class=CommentSerializer,  )  def list_comments(self, request, *args, **kwargs):  Get the log of the blog post based on the parameter value passed in from the URL  post = self.get_object()  Get all comments associated with the article  queryset = post.comment_set.all().order_by("-created_time")  # paginate the comment list to get the comments for the specified page based on the parameters passed in from the URL  page = self.paginate_queryset(queryset)  # serialize comments  serializer = self.get_serializer(page, many=True)  # Return to paginated list of comments  return self.get_paginated_response(serializer.data) Copy the code

We covered the action decorator in detail in the previous tutorial, and here we are again taking a closer look at the action decorator. In addition to setting the methods, detail, and URl_path parameters, You also override the values of these class attributes originally set in PostViewSet by setting pagination_class, serializer_class (for example, for paging, PostViewSet defaults to PageNumberPagination as we set it earlier, instead of LimitOffsetPagination.

The list_Comments method is very logical and explained in detail in the comments. You can also see that we called some helper methods, such as paginate_querySet to page the queryset; Get_paginated_response returns a paginated HTTP response. These methods are all generic helper methods provided by GenericViewSet. The source code is not complicated. But since Django-rest-framework has been written for us, we can reuse it directly. The specific implementation please read the source code to learn.

Now go to the API interaction background and go to the detailed interface of a post, such as/API /posts/5/, and you can see the option of List Comments in the drop-down box:


Click on List Comments to enter the comment List interface of this article and get the comment List resources of this article:



Pay attention to the public account to join the communication group