currently the relationships in our API are represented by a primary key. in This part of the tutorial, we will improve the cohesion and discovery of the API, rather than using hyperlinks to make relationships.
Create an endpoint for the root of our API
Now we have the endpoints of ' snippets ' and ' users ', but our API doesn't have an entry point. To create one, we will use a regular function-based view and @api_view
The adorner we described earlier . in your snippets/views.py
add:
FromRest_framework.DecoratorsImportApi_viewFromRest_framework.ResponseImport ResponseFromRest_framework.ReverseImportReverse@api_view([' GET '])DefApi_root(Request,Format=None): Return response ({ ' users ' :< Span class= "PLN" > Reverse ( ' user-list ' , Request=request, format =format ' snippets ' Span class= "pun" >: Reverse ( ' snippet-list ' , Request=request,< Span class= "PLN" > Format=format)
There are two things to be aware of here. First, we use the function of the rest framework reverse
to return a fully qualified URL; second, the URL pattern is identified by a convenient name, which we will later declare here snippets/urls.py
.
Create an endpoint for a highlighted fragment
Another obvious thing that our Pastebin API is still missing is the code highlighting endpoint.
Unlike all other API endpoints, we don't want to use JSON, just render the HTML representation. The Rest Framework provides two HTML renderer styles, one for processing HTML using template rendering, and the other for processing pre-rendered HTML. The second renderer is the one we want to use for this endpoint.
The other thing we need to consider when creating a code highlighting view is that we can't use the existing, concrete, common view. We are not returning an object instance, but a property of an object instance.
Instead of using a specific generic view, we will use the base class to represent the instance and create our own .get()
method. in your snippets/views.py
add:
FromRest_frameworkImportRenderersFromRest_framework.ResponseImport ResponseClass Snippethighlight(Generics.Genericapiview):Queryset= Snippet.Objects.All()Renderer_classes= (Renderers.Statichtmlrenderer def get ( self, Request, *args, ** snippet = self get_object () return Span class= "Typ" >response (snippet. Highlighted
As always, we need to add a new view that we created in urlconf. We will add a URL pattern for our new API root snippets/urls.py
:
url(r‘^$‘, views.api_root),
Then add a URL pattern to the code snippet highlights:
url(r‘^snippets/(?P<pk>[0-9]+)/highlight/$‘, views.SnippetHighlight.as_view()),
hyperlinks to our API
dealing with the relationships between entities is one of the more challenging aspects of Web API design. We can choose to represent a relationship in a number of different ways:
- Using primary keys
- Use hyperlinks between entities.
- Use a unique identity field on the related entity.
- Uses the default string representation of the related entity.
- Nest related entities within the parent representation.
- Some other custom representations.
The rest framework supports all of these styles and can apply them across forward or reverse relationships, or apply them to custom managers such as universal foreign keys.
in this case, we want to use a hyperlink style between entities. To do this, we will modify our serializer to extend HyperlinkedModelSerializer
instead of the existing ones ModelSerializer
.
in the HyperlinkedModelSerializer
There are the following differences ModelSerializer
:
id
By default does not include the field.
- It includes a
url
field, using HyperlinkedIdentityField
.
- Relationship Usage
HyperlinkedRelatedField
, but not PrimaryKeyRelatedField
.
We can easily rewrite our existing serializer to use the hyperlinks. in your snippets/serializers.py
add:
Class Snippetserializer(serializers.Hyperlinkedmodelserializer):Owner=serializers.Readonlyfield(Source=' Owner.username ')Highlight=serializers.Hyperlinkedidentityfield(View_name=' Snippet-highlight ',Format=' HTML ') Class Meta:Model= SnippetFields= (' URL ', ' ID ', ' Highlight ', ' Owner ', ' Title ', ' Code ', ' Linenos ', ' Language ', ' Style ')Class Userserializer(serializers.Hyperlinkedmodelserializer):Snippets=serializers.Hyperlinkedrelatedfield(Many=true, View_name=< span class= "str" > ' snippet-detail ' , Read_only= true) classmeta: model = user fields = ( ' URL ' , ' ID ' ' username ' , snippets ' /span>
Please note that we have also added a new ‘highlight‘
field. The field is the url
same type as the field , except that it points to the ‘snippet-highlight‘
URL pattern instead of The ‘snippet-detail‘
URL pattern.
because we already include the URL ‘.json‘
of the format suffix , so we still need highlight
to hyperlink that indicates any format suffix on the field it should use the ‘.html‘
suffix.
Make sure our URL pattern is named
if we want to have a hyperlink API, we need to determine our URL pattern. Let's take a look at the URL pattern we need to name.
- The source of our API is
‘user-list‘
the and the ‘snippet-list‘
.
- Our Code snippet serializer includes a referenced field
‘snippet-highlight‘
.
- Our user serializer includes a referenced field
‘snippet-detail‘
.
- our code snippets and user serialization programs include
‘url‘
The fields that will be referenced by default, ‘{model_name}-detail‘
in this case it ‘snippet-detail‘
will be and the ‘user-detail‘
.
by Adding all of these names to our urlconf, our final snippets/urls.py
The file should resemble the following:
FromDjango.Conf.URLsImportUrl,IncludeFromRest_framework.UrlpatternsImportFormat_suffix_patternsFromSnippetsImportViews# API EndpointsUrlpatterns=Format_suffix_patterns([Url(R' ^$ ',Views.Api_root),Url(R' ^snippets/$ ',Views.Snippetlist.As_view(),Name=' Snippet-list '),Url(R' ^snippets/(? p<pk>[0-9]+)/$ ',Views.Snippetdetail.As_view(),Name=' Snippet-detail '),Url(R' ^snippets/(? p<pk>[0-9]+)/highlight/$ ',Views.Snippethighlight.As_view(),Name=' Snippet-highlight '),Url(R' ^users/$ ',Views.UserList.As_view(),Name=' User-list '),Url(R' ^users/(? p<pk>[0-9]+)/$ ',Views.userdetail. Name= ' User-detail ' ]) # Login and Logout Views for the browsable apiurlpatterns += [< Span class= "PLN" > Url (r ' ^api-auth/' ,< Span class= "PLN" > Include ( ' rest_framework.urls ' namespace= ' rest_framework ' ]
Add pagination
The list view of users and code snippets may return quite a few instances, so we really want to make sure that the results are paged out and allow the API client to step through each individual page.
we can pass tutorial/settings.py
Modify our files slightly to change the default list style to use pagination . Add the following settings:
REST_FRAMEWORK = { ‘PAGE_SIZE‘: 10}
Note that the settings in the REST framework are named a single dictionary setting called "Rest_framework", which helps to keep a good separation from your other project settings.
We can also customize the paging style if we also need to, but in this case we will stick to the default.
Browse API
If we open the browser and navigate to the Browsable API, you can learn how the API works by following these links.
You can also see the highlight link on the fragment instance, which will let you go to the highlighted code HTML representation.
Next We'll show you how to use viewsets and routers to reduce the amount of code needed to build the API.
Django Rest Framework-Relational and Hyperlink APIs