Django-rest-frameworkのDBにMongoDBを設定する方法
はじめに
Django-rest-framework(DRF)とMongoDBの連携で検索すると英語の記事が色々と出てはくるのですがベストな方法が分からず、色々と試した結果、個人的にはDjongoを用いるのが良いという結論になったので自分なりにまとめてみました。
この記事では主に、
- DRF + Djongo + MongoDBの連携
- Djongoを利用したModel定義
の二点ついて簡単に紹介してきたいと思います。
Django/DRF初心者の方、これからDRFとMongoDBの連携を考える方の参考になれば幸いです。
環境
python 3.7.3
macOS Mojave 10.14.6
利用するフレームワーク/ライブラリ
Django 2.1.7
djangorestframework 3.9.2
djongo 1.2.33
手順に進む前にこれらをpip installする必要があります。
pythonからMongoDBにアクセスするためのライブラリにはPyMongo1やmongoengine2などがありますが、今回はDjangoとの連携を簡単に行えるDjongoを採用しています。
公式サイト↓
https://nesdis.github.io/djongo/
公式のstartガイドが参考になります↓
https://nesdis.github.io/djongo/integrating-django-with-mongodb/
手順
それでは早速手順に入ります。
まず下記を参考に雛形となるサンプルのREST APIを実装します。
(いきなり丸投げです、すいませんw 全てコピペでOKです。)
https://www.django-rest-framework.org/tutorial/quickstart/
完成すると次のような構造になるはずです。
tutorial
├── db.sqlite3
├── manage.py
└── tutorial
├── __init__.py
├── quickstart
│ ├── __init__.py
│ ├── admin.py
│ ├── apps.py
│ ├── models.py
│ ├── serializers.py
│ ├── tests.py
│ └── views.py
├── settings.py
├── urls.py
└── wsgi.py
この時点ではSQLiteがバックエンドDBとして動いています。
ここからMongoDBを利用するように設定を変更していきます。手順は大きく二つです。
- settings.pyの変更
- modelの修正
settings.pyの変更
まずsettings.pyでDATABASESの部分にdjongoを指定します。
DATABASES = {
'default': {
'ENGINE': 'djongo',
'NAME': 'sample',
}
}
また、INSTALLED_APPSに作成したアプリを登録します。
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework',
'tutorial.quickstart', # これを追加
]
modelの修正
次にmodel定義を修正します。
今回はdjango-rest-frameworkのsampleと違い、自作のモデルAuthor, Bookを作成してみます。
ここで重要なのは、djangoのmodelではなく、djongoのmodels.Modelをimportして継承させるところです。djongoのmodelはdjangoのデフォルトのmodelと基本的に同じインターフェースになっているので、同じ構文でスキーマ定義ができ、インスタンス化したオブジェクトを介してMongoDBに書き込むことも可能です。3
また、modelのfieldにはDjangoのfieldだけでなく、Djongoで独自に定義されるfieldが利用できます。
from djongo import models # djongoのモデルを利用する
class Author(models.Model):
name = models.TextField()
age = models.IntegerField(blank=True)
def __str__(self):
return self.name
class Book(models.Model):
title = models.TextField()
description = models.TextField()
author = models.ForeignKey(Author, on_delete=models.CASCADE)
modelが修正できたので、serializers.py, views.py, urls.pyを今定義したモデルに対応するよう書き換えていきます。
from tutorial.quickstart.models import Author, Book
from rest_framework import serializers
class AuthorSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Author
fields = ['name', 'age']
class BookSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Book
fields = ['title', 'description', 'author']
from tutorial.quickstart.models import Author, Book
from rest_framework import viewsets
from tutorial.quickstart.serializers import AuthorSerializer, BookSerializer
class AuthorViewSet(viewsets.ModelViewSet):
"""
API endpoint that allows users to be viewed or edited.
"""
queryset = Author.objects.all()
serializer_class = AuthorSerializer
class BookViewSet(viewsets.ModelViewSet):
"""
API endpoint that allows groups to be viewed or edited.
"""
queryset = Book.objects.all()
serializer_class = BookSerializer
(余談ですが、views.pyではdjango-rest-frameworkのviewsetの機能によりたったこれだけのコードでCRUDのAPIが全て実装できてしまいます。viewsetとても便利ですね。)
from django.urls import include, path
from rest_framework import routers
from tutorial.quickstart import views
router = routers.DefaultRouter()
router.register(r'authors', views.AuthorViewSet)
router.register(r'books', views.BookViewSet)
# Wire up our API using automatic URL routing.
# Additionally, we include login URLs for the browsable API.
urlpatterns = [
path('', include(router.urls)),
path('api-auth/', include('rest_framework.urls', namespace='rest_framework'))
]
これで実装は完了です。
正しく動作するか確かめるため起動してみます。
migration & サーバー起動
MongoDBを起動します。
sudo mongod
続いて、djangoのコマンドを利用してmigrationとサーバーを起動を行います。
$python manage.py makemigrations quickstart
$python manage.py migrate
$python manage.py runserver
成功すればlocalhost:8000でリッスンするはずです。
ブラウザーのurlにlocalhost:8000/authors/と入れてみます。
画面が表示されました!
この画面からauthorの参照、登録ができます。
また、localhost:8000/books/にアクセスすれば追加したauthorにひもづくbookが登録できます。
最後に、mongoDBの中に本当にデータが入っているか確認してみます。
mongoの対話シェルを起動します。
mongo
対話シェル上で次のようにコマンドを打つことで確認できます。
> use sample
switched to db sample
>
> db.quickstart_author.find({})
{ "_id" : ObjectId("5e049aa6b7135ae9f9ce6862"), "id" : 2, "name" : "奈須きのこ", "age" : 46 }
>
> db.quickstart_book.find({})
{ "_id" : ObjectId("5e049ae7b7135ae9f9ce6865"), "id" : 2, "title" : "空の境界", "description" : "『空の境界』(からのきょうかい)は、奈須きのこによる日本の長編伝奇小説(Wikipediaより)", "author_id" : 2 }
UIと同じデータがちゃんとMongoDBにも登録されていますね。
補足
mongoの中身を見るとquickstart_author, quickstart_bookのようにcollectionが二つに分かれて登録されているのがわかると思います。これはmodel定義の時、以下のようにforeignkeyでモデルをつないでいるためです。
author = models.ForeignKey(Author, on_delete=models.CASCADE)
よりMongoDBらしくデータを格納するには、Djongo独自のEmbeddedModelFieldを利用すれば、bookの中にauthorが入れ子になった状態で一つのcollectionに格納できるようになります。ここは要件に応じて使けになるでしょう。詳しくはこちらの記事が分かりやすく参考になるかと思います。
最後に
以上で手順は全て完了です。ありがとうございました!
少しでもお役に立てると嬉しいです。
Author And Source
この問題について(Django-rest-frameworkのDBにMongoDBを設定する方法), 我々は、より多くの情報をここで見つけました https://qiita.com/Edim/items/90ee83a5d385807f67a6著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .