The first API to make with python Djnago REST framework

: beginner: Create a diary API and publish it from the initial state.

The finished product is here. This is the API that I actually manage my diary. : joy: lol http://www.kojimaiton-philosophy.com/api/diaries/

: pencil: Diary How to use REST_API

CRUD provides the minimum functionality needed for a diary: rocket:

Anyone can get GET, but POST``PUT``DELETE cannot be accessed by anyone, so add an access token to the header. Replace XXXXXX_XXXXXX with the acquired access token.

GET

Get a diary in the list. Pagination, filters and limit offsets are also available.
$ curl http://localhost/api/diaries/

Get one date diary with the date as the primary key.
$ curl http://www.kojimaiton-philosophy.com/api/diaries/2016-12-19/

POST

Put the necessary contents in the diary and create a new one * Since the date is the primary key, you cannot POST the same date twice.
$ curl -X POST http://www.kojimaiton-philosophy.com/api/diaries/ -d "date=2017-03-25" -d "title=Diary title" -d "body=Contents of the diary" -d "publishing=true" -H "Authorization: JWT XXXXXX_XXXXXX"`

PUT

Specify the date you want to update in the path, rewrite it with the data you want to change, and update.
$ curl -X PUT http://www.kojimaiton-philosophy.com/api/diaries/2017-03-25/ -d "date=2017-03-25" -d "title=Change the title of the diary" -d "body=Diary change" -d "publishing=false" -H "Authorization: JWT XXXXXX_XXXXXX"

DELETE

Specify the date you want to delete in the path and delete the data.
$ curl -X DELETE http://www.kojimaiton-philosophy.com/api/diaries/2017-03-25/ -H "Authorization: JWT XXXXXX_XXXXXX"

: earth_asia: environment

CentOS: 7.3.1 Python: 3.6.0 Django: 1.10.6 Restframework: 3.6.2 MySQL: 5.7.17 Nginx: 1.11.13

: chestnut: settings

basic configuration

update yum
$ sudo yum update -y
install git
$ sudo yum install git -y
Put the necessary libraries
$ sudo yum install zlib-devel bzip2 bzip2-devel readline-devel openssl-devel sqlite3 sqlite-devel gcc -y

Port related settings

Turn off firewalld for practice
$ systemctl stop firewalld
firewalld automatic start / stop
$ systemctl disable firewalld
SELinux confirmation
$ getenforce
If Enforcing, edit below and SELINUX=SELINUX enforcing=Rewrite to disabled.
$ sudo vi /etc/selinux/config
If rewritten, restart the machine to reflect the settings
$ sudo shutdown -r now
Make sure it is Disabled
$ getenforce

Install pyenv

$ git clone https://github.com/yyuu/pyenv.git ~/.pyenv
$ echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bash_profile
$ echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bash_profile
$ echo 'eval "$(pyenv init -)"' >> ~/.bash_profile
$ source ~/.bash_profile
$ exec $SHELL -l
Verification
$ pyenv -v

python installation

Check version
$ pyenv install -l
This time 3.6.0 Installation * It takes a long time to complete the installation.
$ pyenv install 3.6.0
Verification
$ pyenv versions
Change default
$ pyenv global 3.6.0
Verification
$ pyenv versions

Install libraries to use with Django

Django installation(python3.Pip is available by default from 6)
$ pip install django
REST_Frame_Work installation
$ pip install djangorestframework
filtering
$ pip install django-filter
Access token by JWT
$ pip install djangorestframework-jwt
Salt mysql with Django
$ pip install PyMySQL
Run Django on a production server
$ pip install uwsgi

: seedling: Create a Django project

Create a project
$ django-admin startproject django_rest_framework
$ cd django_rest_framework
Corrected the host name. Enter the IP / domain you are using.
$ sudo vi django_rest_framework/settings.py
ALLOWED_HOSTS = ['160.16.65.138', 'localhost', '127.0.0.1',]
manage.Start the server with the directory containing the py file and check the connection with a browser. http://Domain name:It can be confirmed at 8000. Ctrl to shut down the server+C
$ python manage.py runserver 0.0.0.0:8000
Settings while the server is running.The debug mode of py is set to true by default, so if you edit the file, it will be reflected on the server immediately.

Check connection from browser スクリーンショット 2017-04-16 午後7.16.13.png

: white_sun_rain_cloud: DB settings

DB settings on the CentOS side

It's easy to use SQLite, but here we will use MySQL, which can be used firmly and universally. (Although the setting is long: joy :)

The db that was created by executing it earlier.Delete sqlite3.
$ ls
db.sqlite3  diary  manage.py
$ rm db.sqlite3
MariaDB is included by default from centos7, so delete it
$ sudo yum remove mariadb-libs -y
If you were using another version of mysql, delete it because that data may remain
$ rm -rf /var/lib/mysql/
Add MySQL repository
$ sudo yum -y install http://dev.mysql.com/get/mysql57-community-release-el6-7.noarch.rpm
Check what can be installed
$ yum repolist enabled | grep "mysql.*-community.*"
Check the information with the info command
$ yum info mysql-community-server
Installation
$ sudo yum -y install mysql-community-server
Version confirmation
$ mysql --version
Automatic start
$ sudo chkconfig mysqld on
Start-up
$ sudo systemctl start mysqld
Check the default password
$ sudo vi /var/log/mysqld.log
Find the following temporary password in the log file. This time, my password is(E,Looks like irsThV0uB
2017-04-01T20:05:05.561190Z 1 [Note] A temporary password is generated for root@localhost: N4IYvEp&)6%!
When you do the following, you will be asked for a password, so enter the password you found above
$ mysql -u root -p
If you do not change the temporary password, it will not accept any processing, so change it. However, please note that this password will not be accepted unless it contains at least 8 characters, letters, numbers, and symbols.
$ ALTER USER root@localhost IDENTIFIED BY '@Mysql0001';
Once set, exit mysql once
$ exit;
Add a line to the following file and set Japanese.[mysqld]Under the character-set-server=Added utf8.
$ sudo vi /etc/my.cnf
The description looks like this ↓
[mysqld]
character-set-server=utf8
Reflect the settings
$ sudo systemctl restart mysqld
Create a DB for use with Django
$ mysql -u root -p
Here, the name is diarydb.
$ create database diarydb;
Finish after creating
$ exit

DB settings on the Django side

Edit settings.py $ vi django_rest_framework/settings.py

django_rest_framework/settings.py


import os
#Import pymysql
import pymysql

#Changed to use mysql
pymysql.install_as_MySQLdb()
DATABASES = {
   'default': {
       'ENGINE': 'django.db.backends.mysql',
       #Database name
       'NAME': 'diarydb',
       #username
       'USER': 'root',
       #password
       'PASSWORD': '@Mysql0001',
       #The IP address and host of the server. Blank is localhost
        'HOST': '',
       #port
       'PORT': '3306',
       'OPTIONS': {
           #Strictly check constraints
           'sql_mode': 'traditional',
       },
       #Test user
        'TEST_NAME': 'auto_tests',
   }
}

Check if Django and MySQL can connect

Create a migration file
$ python manage.py makemigrations
Reflect in DB based on migration file
$ python manage.py migrate

DB setup finished ... Long: joy:

: herb: Edit Django project

Create diary app

$ cd django_rest_framework
$ python manage.py startapp diary

Click here for the current directory structure. It's like adding files little by little here: muscle:

└── django_rest_framework
    ├── diary
    │   ├── __init__.py
    │   ├── admin.py
    │   ├── apps.py
    │   ├── migrations
    │   │   └── __init__.py
    │   ├── models.py
    │   ├── tests.py
    │   └── views.py
    ├── django_rest_framework
    │   ├── __init__.py
    │   ├── __pycache__
    │   │   ├── __init__.cpython-36.pyc
    │   │   ├── settings.cpython-36.pyc
    │   │   ├── urls.cpython-36.pyc
    │   │   └── wsgi.cpython-36.pyc
    │   ├── settings.py
    │   ├── urls.py
    │   └── wsgi.py
    └── manage.py

Define model

The model is one-to-one with the DB. Create models.py $ vi diary/models.py

diary/models.py


# coding: utf-8
from django.db import models
from datetime import date

class Diary(models.Model):
    date = models.DateField(default=date.today, primary_key=True)
    title = models.CharField(max_length=128)
    body = models.TextField()
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    publishing = models.BooleanField(default=True)

Define the created model in settings.py $ vi django_rest_framework/settings.py

django_rest_framework/settings.py



INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    #Add diary
    'diary',
]

Migrate DB again

$ python manage.py makemigrations
$ python manage.py migrate

Enter Django's DB management screen

Create user for admin
$ python manage.py createsuperuser
Start the server.
$ python manage.py runserver 0.0.0.0:8000

Access the administration screen http: // your IP / domain: 8000 / admin /

スクリーンショット 2017-04-16 午後9.29.46.png

Enter the ʻUsername and Passwordcreated increatesuperuser` earlier to enter the management screen. You can click on the GUI to edit or add models.

スクリーンショット 2017-04-16 午後9.26.57.png

Add the model created earlier here so that it can be operated from the GUI. $ vi diary/admin.py

diary/admin.py


# coding: utf-8
from django.contrib import admin
from .models import Diary


@admin.register(Diary)
class Diary(admin.ModelAdmin):
    pass

DIARY has been added to the admin screen: muscle: Let's make some diaries here for use in the API. Diarys -> Add diary -> SAVE

スクリーンショット 2017-04-16 午後10.20.37.png

: ear_of_rice: Introducing REST framework

Define REST framework

$ vi django_rest_framework/settings.py

django_rest_framework/settings.py


INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    #Add diary
    'diary',
    #Add framework
    'rest_framework',
]

Define Serializer

Limit the fields to be output to API in Serializer class $ vi diary/serializer.py

diary/serializer.py


# coding: utf-8
from rest_framework import serializers
from .models import Diary


class DiarySerializer(serializers.ModelSerializer):
    class Meta:
        model = Diary
        fields = ('date', 'title', 'body', 'publishing',)

Define ViewSet

ViewSet is a controller $ vi diary/views.py

diary/views.py


# coding: utf-8
from rest_framework import viewsets
from .models import Diary
from .serializer import DiarySerializer


class DiaryViewSet(viewsets.ModelViewSet):
    queryset = Diary.objects.all()
    serializer_class = DiarySerializer

Define urls

Urls is a URL router setting

Register the created DiaryViewSet $ vi diary/urls.py

diary/urls.py


# coding: utf-8
from rest_framework import routers
from .views import DiaryViewSet

router = routers.DefaultRouter()
router.register(r'diaries', DiaryViewSet)

Routing settings accessed from the outside $ vi django_rest_framework/urls.py

django_rest_framework/urls.py


# coding: utf-8
from django.conf.urls import url, include
from django.contrib import admin
from diary.urls import router as diary_router

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^api/', include(diary_router.urls)),
]

Run and check

Start the server $ python manage.py runserver 0.0.0.0:8000 Connect with browser http: // my IP / domain: 8000 / api / diaries /

スクリーンショット 2017-04-18 4.19.31.png

When I hit it with curl, json is returned.

$ curl http://160.16.65.138:8000/api/diaries/
[{"date":"2017-04-15","title":"Title test","body":"Contents test","publishing":true},{"date":"2017-04-16","title":"title","body":"contents!","publishing":true}]

It is important to note here that the characters are garbled when viewed with json from the pull-down menu with the button next to GET in the above picture. : scream: It may not be garbled depending on the version of Chrome, but it is automatically converted to ʻUTF-8. If you look at it without specifying ʻUTF-8 in Safari etc., it seems that the characters are garbled. To fix the following, you have to specify ʻUTF-8 here for the json` returned to the client.

スクリーンショット 2017-04-19 3.23.12.png

Specify json as utf-8

The REST Framework documentation says UTF-8 by default: joy: $ vi diary/renderers.py Creating a ʻUTF8CharsetJSONRenderer class with ʻUTF-8 The default rest_framework.renderers.JSONRenderer seems to be ʻUTF-8`, but I couldn't. .. ..

diary/renderers.py


from rest_framework.renderers import JSONRenderer


class UTF8CharsetJSONRenderer(JSONRenderer):
    charset = 'utf-8'

Add the following to settings.py $ vi django_rest_framework/settings.py

django_rest_framework/settings.py



REST_FRAMEWORK = {
    'DEFAULT_RENDERER_CLASSES': (
        'diary.renderers.UTF8CharsetJSONRenderer',
    )
}

Garbled characters fixed: muscle:

スクリーンショット 2017-04-19 3.21.25.png

: palm_tree: Check CURD

Change the IP address to your own and request: point_up:

POST(Create)

Create New
$ curl -X POST http://160.16.65.138:8000/api/diaries/ -d "date=2017-04-22" -d "title=Diary title" -d "body=POST test" -d "publishing=true"

PUT(Update)

update
$ curl -X PUT http://160.16.65.138:8000/api/diaries/2017-04-22/ -d "date=2017-04-22" -d "title=Change the title of the diary" -d "body=PUT test" -d "publishing=false"

GET(Read)

Get list
$ curl http://160.16.65.138:8000/api/diaries/
Get by date
$ curl http://160.16.65.138:8000/api/diaries/2017-04-22/

DELETE(Delete)

Delete
$ curl -X DELETE http://160.16.65.138:8000/api/diaries/2017-04-22/

: date: pagination

Add pagination $ vi django_rest_framework/settings.py

django_rest_framework/settings.py


REST_FRAMEWORK = {
    #add to
    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination',
    'PAGE_SIZE': 3,
    'DEFAULT_RENDERER_CLASSES': (
        'diary.renderers.UTF8CharsetJSONRenderer',
    )
}

When you get it, next and previous are added to the root of json, and you can follow the previous and next pages. $ curl http://160.16.65.138:8000/api/diaries/

{
    count: 4,
    next: "http://160.16.65.138:8000/api/diaries/?limit=3&offset=3",
    previous: null,
    results: [
        {
            date: "2017-04-15",
            title: "Title test",
            body: "Contents test",
            publishing: true
        },
        {
            date: "2017-04-16",
            title: "title",
            body: "contents!",
            publishing: true
        },
        {
            date: "2017-04-21",
            title: "hoge",
            body: "ssss",
            publishing: true
        }
    ]
}

: spider_web: filter

Edit views.py $ vi diary/views.py

diary/views.py


# coding: utf-8
from rest_framework import viewsets
from .models import Diary
from .serializer import DiarySerializer


class DiaryViewSet(viewsets.ModelViewSet):
    queryset = Diary.objects.all()
    serializer_class = DiarySerializer
    #Add filter
    filter_fields = ('publishing',)

Edit settings.py $ vi django_rest_framework/settings.py

django_rest_framework/settings.py


REST_FRAMEWORK = {
    #Add filter
    'DEFAULT_FILTER_BACKENDS': ('rest_framework.filters.DjangoFilterBackend',),
    #Add pagination
    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination',
    'PAGE_SIZE': 3,
    'DEFAULT_RENDERER_CLASSES': (
        'diary.renderers.UTF8CharsetJSONRenderer',
    )
}

Try filtering only those with false ? Publish = false in the request

$ curl http://160.16.65.138:8000/api/diaries/?publing=false

{
    count: 1,
    next: null,
    previous: null,
    results: [
        {
            date: "2017-04-22",
            title: "hogehoge",
            body: "hoge",
            publishing: false
        }
    ]
}

: boy_tone1: Authentication

There are various authentication methods, but this time I used JWT (Json Web Token)

Edit settings.py $ vi django_rest_framework/settings.py

django_rest_framework/settings.py


REST_FRAMEWORK = {
    #Add JWT certification
    'DEFAULT_PERMISSION_CLASSES': (
        'rest_framework.permissions.IsAuthenticated',
    ),
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
    ),
    'NON_FIELD_ERRORS_KEY': 'detail',
    'TEST_REQUEST_DEFAULT_FORMAT': 'json',
    #Add filter
    'DEFAULT_FILTER_BACKENDS': ('rest_framework.filters.DjangoFilterBackend',),
    #Add pagination
    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination',
    'PAGE_SIZE': 3,
    'DEFAULT_RENDERER_CLASSES': (
        'diary.renderers.UTF8CharsetJSONRenderer',
    )
}

#Add JWT certification
JWT_AUTH = {
    #Try invalidating the token expiration here
    'JWT_VERIFY_EXPIRATION': False,
}

Edit ʻurls.py $ vi django_rest_framework/urls.py`

django_rest_framework/urls.py


# coding: utf-8
from django.conf.urls import url, include
from django.contrib import admin
from diary.urls import router as diary_router
#Add authentication
from rest_framework_jwt.views import obtain_jwt_token

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^api/', include(diary_router.urls)),
    #Add authentication
    url(r'^api-auth/', obtain_jwt_token),
]

Obtaining a JWT access token

Request with ʻadmin user ʻusername and password created by createsuperuser

$ curl http://160.16.65.138:8000/api-auth/ -d "username=XXXXXXX&password=XXXXXXXX"

If successful, token will be included in the response.

{"token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoyLCJlbWFpbCI6Im11dS5rb2ppbWEudGVzdEBnbWFpbC5jb20iLCJ1c2VybmFtZSI6ImRqYW5nbyIsImV4cCI6MTQ5Mjg1NTMxMH0.m07BcTiAkA79HZ0BC8BsgYOA-SbqmC5GMN5g_QBizZw"}

If the user name and password are different, it will fail as follows

{"detail":["Unable to login with provided credentials."]}

Edit views.py and authenticate $ vi diary/views.py

diary/views.py


# coding: utf-8
from rest_framework import viewsets
from .models import Diary
from .serializer import DiarySerializer
#Add authentication
from rest_framework import permissions


class DiaryViewSet(viewsets.ModelViewSet):
    queryset = Diary.objects.all()
    serializer_class = DiarySerializer
    #Add filter
    filter_fields = ('publishing',)
    #Add authentication If you want to authenticate all CURD(permissions.IsAuthenticated,)To
    permission_classes = (permissions.IsAuthenticatedOrReadOnly,)

Try to be authenticated

Create New

$ curl -X POST http://160.16.65.138:8000/api/diaries/ -d" date = 2017-04-21 "-d" title = authentication "-d" body = authentication test "-d" publishing = true " `

Since there is no access token, it is OK if it fails as follows!

{"detail":"Authentication credentials were not provided."}

POST with the acquired access token * Change the access token to your own

$ curl -X POST http://160.16.65.138:8000/api/diaries/ -d "date=2017-04-10" -d "title=Authentication" -d "body=Authenticationのテスト" -d "publishing=true" -H "Authorization: JWT eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoyLCJlbWFpbCI6Im11dS5rb2ppbWEudGVzdEBnbWFpbC5jb20iLCJ1c2VybmFtZSI6ImRqYW5nbyIsImV4cCI6MTQ5Mjg1NTMxMH0.m07BcTiAkA79HZ0BC8BsgYOA-SbqmC5GMN5g_QBizZw"

Once created, make sure everything except GET is authenticated: fist:

Fixed 404 page to normal.

When you access the current route, Django defaults to: http://160.16.65.138:8000/

スクリーンショット 2017-04-22 19.51.16.png

Edit settings.py and set DEBUG = False according to the wording at the bottom. * If you set DEBUG = False, the file changes cannot be reflected automatically while starting the server. So be careful You're seeing this error because you have DEBUG = True in your Django settings file. Change that to False, and Django will display a standard 404 page.

$ vi django_rest_framework/settings.py

django_rest_framework/settings.py



...abridgement

# DEBUG =If set to False, it will be a normal 404 page.
DEBUG = False

...abridgement

When I accessed it, it became a normal 404 page!

スクリーンショット 2017-04-22 19.57.24.png

: robot: test case

tests.Remove py
$ rm diary/tests.py
Create a test directory. Put the test here
$ mkdir diary/tests
To be recognized as a python directory`__init__.py`Add. Nothing in particular is described.
$ vi diary/tests/__init__.py

Create test_diary.py for authentication and CRUD testing

$ vi diary/tests/test_diary.py

diary/tests/test_diary.py


# coding: utf-8
from rest_framework import status
from rest_framework.test import APITestCase
from rest_framework_jwt.compat import get_user_model
from rest_framework_jwt.settings import api_settings


class DiaryTest(APITestCase):
    def setUp(self):
        #Issuance of access token
        User = get_user_model()
        self.username = 'test_user'
        self.email = '[email protected]'
        self.user = User.objects.create_user(self.username, self.email)
        jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
        jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER
        payload = jwt_payload_handler(self.user)
        token = jwt_encode_handler(payload)
        self.auth = 'JWT {0}'.format(token)
        self.url = '/api/diaries/'

    def test_diary_api(self):
        # POST
        data = {
            "date": "2011-11-11",
            "title": "title",
            "body": "body",
            "publishing": True,
        }
        response = self.client.post(self.url, data, HTTP_AUTHORIZATION=self.auth)
        self.assertEqual(response.status_code, status.HTTP_201_CREATED)
        self.assertEqual(response.data, data)

        # GET
        expected_get_data = {
            "count": 1,
            "next": None,
            "previous": None,
            "results": [
                {
                    "date": "2011-11-11",
                    "title": "title",
                    "body": "body",
                    "publishing": True,
                }
            ]
        }
        response = self.client.get(self.url)
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertEqual(response.data, expected_get_data)

        # PUT
        data2 = {
            "date": "2010-10-10",
            "title": "title",
            "body": "body",
            "publishing": False,
        }
        response = self.client.put(self.url + '2011-11-11/', data2, HTTP_AUTHORIZATION=self.auth)
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertEqual(response.data, data2)

        # DELETE
        response = self.client.delete(self.url + '2010-10-10/', HTTP_AUTHORIZATION=self.auth)
        self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT)

Run the test

The following will run test_xxxx.py in tests. $ ./manage.py test

The test passed!


[xxxxx@tk2-208-13884 django_rest_framework]$ ./manage.py test
Creating test database for alias 'default'...
System check identified no issues (0 silenced).
.
----------------------------------------------------------------------
Ran 1 test in 0.049s

OK
Destroying test database for alias 'default'...

: mailbox_with_mail: Reverse proxy settings (Delete: 8000 on API endpoint)

nginx installation

Create a file of nginx.repo because we will add a repository $ sudo vi /etc/yum.repos.d/nginx.repo

nginx.repo


[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/mainline/centos/7/$basearch/
gpgcheck=0
enabled=1

Install and launch

install nginx
$ sudo yum install nginx -y
Check version
$ nginx -v
Auto start setting
$ sudo systemctl enable nginx
Start-up
$ sudo systemctl start nginx

Check the default page

Check the display. http: // IP of my server / Below is my example. http://160.16.65.138/

スクリーンショット 2017-04-22 20.47.25.png

Set up a reverse proxy

Create a file with the name XXX.conf under /etc/nginx/conf.d Here, it is called server.conf, and the request received at number 80 is forwarded to number 8000. $ sudo vi /etc/nginx/conf.d/server.conf

server.conf


server {
     listen 80;
     #An accessible IP address or domain. Below is my example
     server_name 160.16.65.138;
     proxy_set_header X-Real-IP $remote_addr;
     proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
     proxy_set_header Host $http_host;
     proxy_redirect off;
     proxy_max_temp_file_size 0;
     location / {
        #Forwarding destination
        proxy_pass http://localhost:8000;
     }:joy:
}

Reboot nginx to reflect the settings

$ sudo systemctl restart nginx

When executed, it will be accessible from the browser with the default HTTP 80, so 8000 is unnecessary. python manage.py runserver 0.0.0.0:8000

スクリーンショット 2017-04-22 21.09.22.png

: camping: Start Django as a daemon and run it in production

Try to keep it running in the background even if you exit` from the server.

Set password for root
$ sudo passwd root
Become the root
$ su
Run Django with a production daemon
$ uwsgi --http :8000 --module django_rest_framework.wsgi --daemonize /var/log/uwsgi-django.log

Now it should be running in the background! To stop ʻuwsgirunning in the background,kill the PID` of the running server.

Find out $ netstat -ntlp

It is displayed next to ʻuwsgi, but since it is PID, In this case kill -9 32215` will stop the server

Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      32181/nginx: master
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      861/sshd
tcp        0      0 0.0.0.0:8000            0.0.0.0:*               LISTEN      32215/uwsgi
tcp        0      0 127.0.0.1:43047         0.0.0.0:*               LISTEN      32215/uwsgi
tcp6       0      0 :::22                   :::*                    LISTEN      861/sshd
tcp6       0      0 :::3306                 :::*                    LISTEN      19382/mysqld

How to read ʻuwsgi` seems to be whiskey? I read "Uesugi": joy:

: cat: Summary

Put the finished product on Github: bulb:

https://github.com/MuuKojima/django_rest_framework

This is the API that I actually manage my diary. : joy: lol

http://www.kojimaiton-philosophy.com/api/diaries/ While expanding, we will continue to operate for a lifetime: muscle: This is operated on AWS!

reference

http://qiita.com/redamoon/items/eabaacabb5b1a0c34ca3 http://qiita.com/seizans/items/05a909960820dd92a80a http://racchai.hatenablog.com/entry/2016/05/08/070000 http://var.blog.jp/archives/70125676.html

Recommended Posts

The first API to make with python Djnago REST framework
Create a REST API to operate dynamodb with the Django REST Framework
Call the API with python3.
[First API] Try to get Qiita articles with Python
The first algorithm to learn with Python: FizzBuzz problem
Hit the Etherpad-lite API with Python
[Python] The first step to making a game with Pyxel
Operate Jupyter with REST API to extract and save Python code
Rubyist tried to make a simple API with Python + bottle + MySQL
A story about adding a REST API to a daemon made with Python
Implementation of CRUD using REST API with Python + Django Rest framework + igGrid
[September 2020 version] Explains the procedure to use Gmail API with Python
Create REST API that returns the current time with Python3 + Falcon
Image upload & download to Azure Storage. With Python + requests + REST API
How to send a request to the DMM (FANZA) API with python
Make the Python console covered with UNKO
Fractal to make and play with Python
Let's make a web framework with Python! (1)
Let's make a web framework with Python! (2)
The road to compiling to Python 3 with Thrift
[Python] To get started with Python, you must first make sure you can use Python.
I tried to get the authentication code of Qiita API with Python.
I tried to get the movie information of TMDb API with Python
The easiest way to synthesize speech with python
Try to solve the man-machine chart with Python
Introduction to Tornado (1): Python web framework started with Tornado
Specify the Python executable to use with virtualenv
I want to make a game with Python
Say hello to the world with Python with IntelliJ
Try to make a "cryptanalysis" cipher with Python
The easiest way to use OpenCV with python
Use the Python framework "cocotb" to test Verilog.
Introduction to Python with Atom (on the way)
Try to make a dihedral group with Python
[Introduction to Udemy Python3 + Application] 9. First, print with print
Knowledge notes needed to understand the Python framework
[Python] Mention to multiple people with Slack API
Let's create it by applying Protocol Buffer to the API with Serverless Framework.
How to automatically generate API document with Django REST framework & POST from document screen
Note: How to get the last day of the month with python (added the first day of the month)
If you want to make a discord bot with python, let's use a framework
To automatically send an email with an attachment using the Gmail API in Python
I want to create an API that returns a model with a recursive relationship in the Django REST Framework
Try to make a command standby tool with python
[Introduction to Python] How to iterate with the range function?
Explain in detail how to make sounds with python
Try to solve the internship assignment problem with Python
I tried to touch the CSV file with Python
I tried to solve the soma cube with python
[Python] How to specify the download location with youtube-dl
Create a Todo app with the Django REST framework
Try to make RESTful API with MVC using Flask 1.0.2
Make a breakpoint on the c layer with python
Convert the image in .zip to PDF with Python
When you want to filter with Django REST framework
I want to inherit to the back with python dataclass
The first step to getting Blender available from Python
Specify MinGW as the compiler to use with Python
I tried to solve the problem with Python Vol.1
[Python] How to rewrite the table style with python-pptx [python-pptx]
Note calling the CUDA Driver API with Python ctypes