API (II)

Source: Internet
Author: User
Tags virtual environment virtualenv

virtualenvis a tool to create isolated Python environments.

to create a new environment

Before we do anything else we ' ll create a new virtual environment, using VIRTUALENV. This would make sure our package configuration was kept nicely isolated from any other projects we ' re working on.

# Create an isolated space virtualenv envsource env/bin/activate

Now the we ' re inside a virtualenv environment, we can install our package requirements.

# Install the required module PIP install djangopip install djangorestframeworkpip install pygments # We'll be using the-the  code HIGHL Ighting

Note: To exit the VIRTUALENV environment at any time, just type deactivate . For more information see the virtualenv documentation.

Entry

Summary : The Getting Started section creates a Django project.

Okay, we ' re ready to get coding. To get started, let's create a new project to work with.

# Create a project under Linux CD ~django-admin.py startproject tutorialcd tutorial[email protected]:~$ Tree tutorialtutorial├── Manage.py└──tutorial        ├──__init__.py        ├──settings.py        ├──urls.py        └──wsgi.py1 directory, 5 files

Once that's done we can create the app that we'll use to create a simple Web API.

# Create a Apppython manage.py Startapp snippets

We ' ll need to add our new snippets app and the rest_framework app to INSTALLED_APPS . Let ' s edit the tutorial/settings.py file:

# config file Installed_apps = (...    ')    Rest_framework ',    ' snippets.apps.SnippetsConfig ',)

Please note this if you ' re using the Django <1.9, you need-to-replace with snippets.apps.SnippetsConfig snippets .

Okay, we ' re ready for roll.

Create a model that you can use

For the purposes of this tutorial we ' re going to start by creating a simple  Snippet  model that I s used to store code snippets. Go ahead and edit the  snippets/models.py  file. Note:good programming practices include comments. Although you'll find them in our repository version of this tutorial code, we had omitted them here's focus on the Cod E itself.

# models.py

From django.db import modelsfrom pygments.lexers import get_all_lexersfrom pygments.styles Import get_all_styleslexers = [item for item in Get_all_lexers () if ITEM[1]] Language_choices = sorted ([(Item[1][0], item[0]) for item in lexers]) style_choices = sorted (item, item) for item in Get_a Ll_styles ()) class Snippet (models. Model): created = models. Datetimefield (auto_now_add=true) title = models. Charfield (max_length=100, Blank=true, default= ") code = models. TextField () Linenos = models. Booleanfield (default=false) language = models. Charfield (choices=language_choices, default= ' python ', max_length=100) style = models. Charfield (choices=style_choices, default= ' friendly ', max_length=100) class Meta: ordering = (' created ',) #排序字段

We ' ll also need to create a initial migration for our snippet model, and sync the database for the first time.

# Initialize database python manage.py makemigrations snippetspython manage.py Migrate
Create a serializer class

The first thing we need to get started in our Web API are to provide a a-to-be serialization and deserialization of the snippet instances into represent Ations such as json . We can do this by declaring serializers, very similar to Django ' s forms. Create a file snippets in the directory named serializers.py and add the following.

#serializers. Pyfrom rest_framework Import serializersfrom snippets.models import Snippet, language_choices, Style_ Choicesclass Snippetserializer (serializers. Serializer): id = serializers. Integerfield (read_only=true) title = serializers. Charfield (Required=false, Allow_blank=true, max_length=100) code = serializers. Charfield (style={' base_template ': ' textarea.html '}) Linenos = serializers. Booleanfield (required=false) language = serializers. Choicefield (choices=language_choices, default= ' python ') style = serializers. Choicefield (choices=style_choices, default= ' friendly ') def create (self, validated_data): "" "Create and R        Eturn a new ' Snippet ' instance, given the validated data.        "" "Return Snippet.objects.create (**validated_data) def update (self, instance, Validated_data):" "        Update and return an existing ' Snippet ' instance, given the validated data. "" "Instance.title = Validated_data.get (' title ', Instance.title)        Instance.code = validated_data.get (' code ', instance.code) Instance.linenos = Validated_data.get (' Linenos ', Instance.linenos) Instance.language = Validated_data.get (' language ', instance.language) Instance.style = val Idated_data.get (' style ', Instance.style) Instance.save () Return instance

The first part of the serializer class defines the fields that get serialized/deserialized. The create() and update() methods define how fully fledged instances is created or modified when callingserializer.save()

A serializer class is very similar to a Django Form class, and includes similar validation flags on the various fields, s Uch required as, max_length and default .

The field flags can also control how the serializer should is displayed in certain circumstances, such as when rendering t o HTML. The flag above is {‘base_template‘: ‘textarea.html‘} equivalent to using on widget=widgets.Textarea a Django Form class. This was particularly useful for controlling how the browsable API should be displayed, as we'll see later in the tutorial.

In fact, we can also use the ModelSerializer class to save some time, as we ll see later, but for now we'll keep our serializer definition explicit.

Using the serializers Serializer

Summary : This section is all operated under the Python shell.

Before we go any further we ' ll familiarize ourselves with the using our new serializer class. Let's drop into the Django shell.

# python shell under Python manage.py shell

Okay, once we ' ve got a few imports out of the the the-a-, let's create a couple of code snippets to work with.

#from snippets.models Import snippetfrom snippets.serializers import Snippetserializerfrom rest_framework.renderers Import jsonrendererfrom rest_framework.parsers Import Jsonparsersnippet = Snippet (code= ' foo = "bar" \ n ')   # Instantiate an object and fill in the Code field and save. Snippet.save () snippet = snippet (code= ' Print "Hello, world" \ n ') Snippet.save ()

We ' ve now got a few snippet instances to play with. Let's take a look at serializing one of those instances.

# serializer = Snippetserializer (snippet)   #snippet是类Snippet的对象
Serializer.data # {' id ': 2, ' title ': U ', ' Code ': U ' print ' Hello, world ' \ n ', ' Linenos ': False, ' language ': U ' python ', ' sty Le ': U ' Friendly '}

At this point we ' ve translated the model instance into Python native datatypes. To finalize the serialization process we render the data into json .

#content = Jsonrenderer (). Render (Serializer.data) content# ' {"id": 2, "title": "", "Code": "Print \ \" Hello, world\\ "\\n", "Linenos": false, "language": "Python", "style": "Friendly"} '

Deserialization is similar. First we parse a stream into Python native datatypes ...

#from django.utils.six Import bytesiostream = Bytesio (content) data = Jsonparser (). Parse (Stream)

... then we restore those native datatypes into a fully populated object instance.

#serializer = Snippetserializer (data=data) serializer.is_valid () # trueserializer.validated_data# OrderedDict ([' Title ', '), (' Code ', ' print ' Hello, world "\ n '), (' Linenos ', False), (' Language ', ' Python '), (' style ', ' friendly ')]) seria Lizer.save () # <snippet:snippet object>

Please note that the API is similar to forms. The similarity is even more pronounced when we start the writing views and the use of our serializer.

We can also instantiate querysets instead of model instances. To do this, we just add a flag to the many=True serializer arguments.

#serializer = Snippetserializer (Snippet.objects.all (), many=true) serializer.data# [ordereddict (' id ', 1), (' title ', U "), (' Code ', u ' foo =" bar "\ n '), (' Linenos ', False), (' Language ', ' Python '), (' style ', ' friendly ')]), ordereddict ([' ID ' , 2), (' title ', U '), (' Code ', u ' print "Hello, world" \ n '), (' Linenos ', False), (' Language ', ' Python '), (' style ', ' friendly ')], ordereddict ([' ID ', 3), (' title ', U '), (' Code ', u ' print "Hello, World"), (' Linenos ', False), (' Language ', ' Python ') ), (' style ', ' friendly ')]]
Using Modelserializers

SnippetSerializerOur class was replicating a lot of information that's also contained in the Snippet model. It would be nice if we could keep our code more concise.

available Form with Django Classes and ModelForm class in the same way that the rest framework includes Serializer Classes and ModelSerializer class.

Let's take a look at using ModelSerializer class to reconstruct our serializer. Open the file again snippets/serializers.py , and replace the class with the SnippetSerializer following.

#class Snippetserializer (serializers. Modelserializer):    class Meta:        model = Snippet Fields        = (' id ', ' title ', ' Code ', ' Linenos ', ' language ', ' style ‘)

Serializers has a good property is that you can check all fields of a serializer instance by the printing its representation. Open the Django shell python manage.py shell with, and then try the following:

#from snippets.serializers Import Snippetserializerserializer = Snippetserializer () print (repr (serializer)) # Snippetserializer (): #    id = Integerfield (label= ' id ', read_only=true) #    title = Charfield (Allow_blank=true, Max _length=100, Required=false) #    code = Charfield (style={' base_template ': ' textarea.html '}) #    Linenos = Booleanfield (required=false) #    language = Choicefield (choices=[(' Clipper ', ' FoxPro '), (' Cucumber ', ' Gherkin '), (' Robotframework ', ' robotframework '), (' ABAP ', ' ABAP '), (' Ada ', ' Ada ') ... #    style = Choicefield (choices=[(' Autumn ', ' Autumn '), (' Borland ', ' Borland '), (' BW ', ' bw '), (' colorful ', ' colorful ') ...

Notes ModelSerializer that classes don ' t anything particularly magical, they is simply a shortcut for creating serializer Classe S

    • A automatically determined set of fields.
    • Simple default implementations for the create() and update() methods.
use our serializer to write a normal Django view

Let's take a look at how to use the new serializer class to write some API views. We are not currently using any rest framework for other functions, we only write some general Django view functions.

Edit snippets/views.py the file and add the following content.

#from django.http import HttpResponse, jsonresponsefrom django.views.decorators.csrf import Csrf_exemptfrom rest_ Framework.renderers Import jsonrendererfrom rest_framework.parsers import jsonparserfrom snippets.models Import Snippetfrom snippets.serializers Import Snippetserializer

The root of our API will be a view that supports listing all existing fragments, or creating a new fragment.

# @csrf_exemptdef Snippet_list (Request): "" "    List all code snippets, or create a new snippet.    " " if Request.method = = ' GET ':        snippets = Snippet.objects.all ()        serializer = Snippetserializer (snippets, many= True)        return Jsonresponse (Serializer.data, Safe=false)    elif Request.method = = ' POST ':        data = Jsonparser () . Parse (Request)        serializer = Snippetserializer (data=data)        if Serializer.is_valid ():            serializer.save ()            return Jsonresponse (Serializer.data, status=201)        return Jsonresponse (serializer.errors, status=400)

Note that because we want to be able to access this view function from a client that does not have CSRF token, we need to use csrf_exempt标记视图 the . This is not something you usually want to do, the rest framework view actually uses more obvious behavior than this, but it will now be used for our purposes.

We also need a view corresponding to an individual snippet and can be used to retrieve, update or delete the snippet.

# @csrf_exemptdef Snippet_detail (Request, PK): "" "    Retrieve, update or delete a code snippet.    " " Try:        snippet = Snippet.objects.get (PK=PK)    except snippet.doesnotexist:        return HttpResponse (status=404)    if Request.method = = ' GET ':        serializer = Snippetserializer (snippet)        return Jsonresponse (serializer.data )    elif Request.method = = ' PUT ':        data = Jsonparser (). Parse (request)        serializer = Snippetserializer ( Snippet, data=data)        if Serializer.is_valid ():            serializer.save ()            return Jsonresponse ( Serializer.data)        return Jsonresponse (serializer.errors, status=400)    elif Request.method = = ' DELETE ':        snippet.delete ()        return HttpResponse (status=204)

Finally, we need to connect these view functions together. to create a snippets/urls.py file:

#from django.conf.urls Import urlfrom Snippets Import viewsurlpatterns = [    url (R ' ^snippets/$ ', views.snippet_list),    URL (r ' ^snippets/(? p<pk>[0-9]+)/$ ', Views.snippet_detail),]

We also need to tutorial/urls.py The file connects to the root urlconf to contain the URL of our fragment application.

#from django.conf.urls Import url, includeurlpatterns = [    url (r ' ^ ', include (' Snippets.urls ')),]

It ' s worth noting that there is a couple of edge cases we ' re not dealing with properly at the moment. If we send malformed json , or if a request is made with a method that the view doesn ' t handle and then we'll end up with a 5 XX "Server Error" response. Still, this ' ll does for now.

Test our first attempt on the Web API

Now we can start a sample server that runs our code snippet.

Exit Shell ...

Quit ()

... and start up Django ' s development server.

#python manage.py runservervalidating Models ... 0 Errors Founddjango version 1.11, using Settings ' tutorial.settings ' development server is running at http://127.0.0.1:800 0/quit the server with Control-c.

In another terminal window, we can test the server.

we can use Curl or Httpie to test our API . Httpie is a user-friendly HTTP client written in Python. Let's install it.

You can use Pip to install Httpie:

#pip Install Httpie

Finally, we can get a list of all the fragments:

#http http://127.0.0.1:8000/snippets/HTTP/1.1 ... [  {    "id": 1,    "title": "",    "code": "foo = \" Bar\ "\ n",    "Linenos": false,    "language": "Python", "    style": "Friendly"  },  {    "id": 2,    "title": "",    "code": "Print \" Hello, world\ "\ n",    "Linenos": false,    "language": " Python ",    " style ":" Friendly "  }]

Or we can get a specific snippet by referencing its ID:

#http http://127.0.0.1:8000/snippets/2/HTTP/1.1 ... {  "id": 2,  "title": "",  "code": "Print \" Hello, world\ "\ n",  "Linenos": false,  "language": " Python ",  " style ":" Friendly "}

Similarly, you can show the same by accessing these URLs in a Web browser?? The JSON.

API (II)

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.