API (v) Relationships & hyperlinked APIs

Source: Internet
Author: User

Currently, the relationships in our API are represented by a primary key. in this part of the tutorial, we will improve the cohesion and visibility of the API, rather than using the associated hyperlinks.

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 an entry point, we will use a regular function-based view and the adorner we described earlier @api_view . in your snippets/views.py add:

From rest_framework.decorators import api_viewfrom rest_framework.response import Responsefrom rest_framework.reverse Import Reverse@api_view ([' GET ']) def api_root (Request, Format=none):    return Response ({        ' users ': Reverse (' User-list ', Request=request, Format=format),        ' snippets ': reverse (' snippet-list ', Request=request, Format=format )    })

There are two things to be aware of here. First, we use the rest framework's reverse functions to return fully qualified URLs, and secondly, the URL pattern is identified by a convenient name, which we will later snippets/urls.py中 declare.

Create an endpoint for highlighted snippets

Another obvious thing that remains missing from our Pastebin API is the code highlighting endpoints.

Unlike all other API endpoints, we do not want to use JSON, but just render the HTML presentation layer. The rest framework provides two kinds of HTML renderer styles, one that uses templates to resolve HTML rendering, and another that uses pre-rendered HTML. The second renderer is the one we want to use for this endpoint.

Another thing we need to consider when creating a code highlighting view is that there is no ready-made, generic view for us to use. Instead of returning an object instance, we return the properties of an object instance.

Instead of using a specific generic view, we use the base class to represent the instance and create our own .get() methods. In your snippets/views.py add :

From rest_framework import renderersfrom rest_framework.response import Responseclass snippethighlight (generics. Genericapiview):    queryset = Snippet.objects.all ()    renderer_classes = (renderers. Statichtmlrenderer,)    def get (self, request, *args, **kwargs):        snippet = Self.get_object ()        return Response (snippet.highlighted)

As always, we need to add a new view in urlconf. We will add snippets/urls.py a URL pattern to our new API root in:

URL (r ' ^$ ', views.api_root),

Then add a URL pattern for snippet highlights:

URL (r ' ^snippets/(? p<pk>[0-9]+)/highlight/$ ', views. Snippethighlight.as_view ()),
Hyperlinking our API

Dealing with the relationship between entities is one of the more challenging aspects of Web API design. We can choose a number of different ways to represent a relationship:

    • Use a primary key.
    • 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 be applied to a forward or reverse relationship, or to a custom manager such as a generic foreign key.

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 ModelSerializer existing ones.

HyperlinkedModelSerializerWith the ModelSerializer following differences:

    • The ID field is not included by default.
    • It includes a use HyperlinkedIdentityField的url字段 .
    • The relationship HyperlinkedRelatedField is used instead of PrimaryKeyRelatedField .

We can use hyperlinks to easily rewrite our existing serializer. 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 = Snippet        Fields = (' URL ', ' id ', ' highlight ', ' owner ', '                  title ', ' Code ', ' Linenos ', ' language ', ' style ') class Userserializer ( serializers. Hyperlinkedmodelserializer):    snippets = serializers. Hyperlinkedrelatedfield (many=true, view_name= ' Snippet-detail ', read_only=true)    class Meta:        model = User Fields        = (' URL ', ' id ', ' username ', ' snippets ')

Note that we have also added a new ‘highlight‘ field. This field has the same type as the URL field, except that it points to the ‘snippet-highlight‘ URL pattern instead of the ‘snippet-detail‘ URL pattern.

Because we include the URL of the format suffix, ‘.json‘ We also need to indicate on the highlight field that any hyperlink that returns a format suffix should use a ‘.html‘ suffix.

Making sure our URL patterns is named

If we want to use the hyperlink type API, then we need to name the URL pattern. Let's take a look at the URL pattern we need to name.

    • The source of our API is to refer to ‘user-list‘ and ‘snippet-list‘ .
    • Our fragment serializer includes a referenced ‘snippet-highlight‘ field.
    • Our user serializer includes a referenced ‘snippet-detail‘ field.
    • Our fragment and user serializer includes ‘{model_name}-detail‘ the ' url ' field that will be referenced by default, in which case it will be ‘snippet-detail‘ and ‘user-detail‘ .

After adding all of these names to our urlconf, the final snippets/urls.py file should look like this:

From django.conf.urls import URL, includefrom rest_framework.urlpatterns import format_suffix_patternsfrom Snippets Import views# 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.as_view (),        name= ' User-detail ')] # Login and logout views for the browsable apiurlpatterns + = [    URL ( R ' ^api-auth/', 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 want to make sure that the results are paged out and allow the API client to step through each individual page.

We can change the tutorial/settings.py default list style to use pagination by slightly modifying our files. 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 maintain a good separation from other project settings.

We can also customize the paging style if we need to, but in this case we will stick to the default.

API (v) Relationships & hyperlinked APIs

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.