ホーム 記事一覧 ブック DH週間トピックス 検索 このサイトについて
English
GakuNin RDM Search API (`/api/v1/search/`) 調査メモ

GakuNin RDM Search API (`/api/v1/search/`) 調査メモ

調査日 : 2026-02-24 対象 : GakuNin RDM (GRDM) の Search API ソースコード : RCOSDP/RDM-osf.io(website/search/ ディレクトリ) 開発者ガイド : RCOSDP/RDM-developer-guide 注意 : Search API の公式ドキュメントは確認できませんでした。本稿は API の実際の挙動とソースコードの両方に基づく調査記録です。 概要 GakuNin RDM は OSF (Open Science Framework) のフォークであり、ソースコードは GitHub (RCOSDP/RDM-osf.io) で公開されています。検索機能の実装は website/search/ ディレクトリにあり、主に以下のファイルで構成されています。 ファイル 役割 elastic_search.py インデックスのマッピング定義、ドキュメントの登録・更新 views.py API エンドポイントのハンドラ util.py build_private_search_query() 等のクエリ構築 search.py 上位インターフェース POST https://rdm.nii.ac.jp/api/v1/search/ Authorization: Bearer <パーソナルアクセストークン> 日本語環境では Elasticsearch の kuromoji_analyzer が使用されています(ソースコードで確認)。 リクエスト形式 { "api_version": {"vendor": "grdm", "version": 2}, "elasticsearch_dsl": { "query": { "filtered": { "query": { "query_string": { "default_field": "_all", "query": "検索キーワード" } } } }, "from": 0, "size": 10 }, "highlight": "title:30,name:30,user:30,text:124,comments.*:124", "sort": "modified_desc" } パラメータ 説明 備考 api_version vendor: "grdm", version: 2 version は 1 と 2 をサポートしています(ソースコードで確認) elasticsearch_dsl.query Elasticsearch Query DSL filtered 形式(ES 2.x 系構文)です from / size ページネーション size=100 まで動作を確認しています。match_all + size>50 では 500 エラーになります highlight フィールド名:文字数 形式 GRDM 独自フォーマットです。ワイルドカード(comments.*)も使えます sort ソート順 後述します sort の選択肢 ソースコード(util.py の build_private_search_query)によると、以下のソート対象が定義されています。 ...

Github Actionsを使ってGithubからEC2までのDjangoのCICD環境構築(2023版)

Github Actionsを使ってGithubからEC2までのDjangoのCICD環境構築(2023版)

概要 Github Actionsを使ってGithubからEC2までのDjangoのCICD環境を構築する機会があり、その備忘録です。 以下の記事を参考にさせていただきました。 https://qiita.com/fffukken/items/27b0bfa712940914d3f6 上記の記事に対して、Github Actionsの設定を一部更新しました。 Github Actionsの設定 name: Test and Deploy on: push: branches: [ develop, main ] pull_request: branches: [ develop ] jobs: build: runs-on: ubuntu-latest strategy: max-parallel: 4 matrix: python-version: [3.9, "3.10"] steps: - uses: actions/checkout@v3 - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v4 with: python-version: ${{ matrix.python-version }} - name: Install Dependencies run: | python -m pip install --upgrade pip pip install -r requirements.txt - name: Run Tests run: | python manage.py makemigrations python manage.py migrate python manage.py test - name: deploy run: | echo "$SECRET_KEY" > secret_key chmod 600 secret_key ssh -oStrictHostKeyChecking=no ${EC2_USER}@${EC2_HOST} -i secret_key "source <仮想環境名>/bin/activate \ && cd ~/<プロジェクト名>\ && git pull origin main \ && python manage.py makemigrations \ && python manage.py migrate \ && deactivate \ && sudo systemctl restart gunicorn" env: SECRET_KEY: ${{ secrets.SECRET_KEY }} EC2_USER: ${{ secrets.EC2_USER }} EC2_HOST: ${{ secrets.EC2_HOST }} 変更した点として、actions/checkoutとactions/setup-pythonのバージョンを変更しました。また、pip installの部分を変更し、pip install -r requirements.txtにしました。 ...

django-simple-history: Djangoでモデルの編集履歴を記録する

django-simple-history: Djangoでモデルの編集履歴を記録する

概要 Djangoで編集履歴を残す方法を調べたので、その備忘録です。 以下のメッセージのように、デフォルトでは、管理画面を通じた編集履歴は記録されるが、それ以外の画面を通じた編集履歴は残らないようでした。 This object doesn’t have a change history. It probably wasn’t added via this admin site. django-simple-history そこで、以下のパッケージを使ってみます。 https://django-simple-history.readthedocs.io/en/latest/ 以下のクイックスタートのページを参考にすることで、問題なく利用できました。 https://django-simple-history.readthedocs.io/en/latest/quick_start.html 参考 以下のように、編集履歴に関するテーブルが追加され、編集履歴が記録されるようになりました。 また管理画面から、以下のような編集履歴を確認できるようになりました。管理画面以外の画面からの変更履歴を確認できました。 まとめ Djangoで編集履歴を残す際に参考になりましたら幸いです。

Django Rest Framework (DRF)で部分一致フィルタを実装する

Django Rest Framework (DRF)で部分一致フィルタを実装する

Django Rest Framework (DRF)で部分一致フィルタを実装するためには、Djangoフィルターバックエンドを使うのが一般的です。これは、django_filters モジュールを使用します。 このモジュールをまだインストールしていない場合は、以下のコマンドでインストールできます: pip install django-filter 以下は、部分一致検索を実現するための一般的な手順です: フィルタセットを定義します。以下はmodels.pyに存在するMyModelというモデルでnameフィールドを部分一致検索するためのフィルタセットです: import django_filters class MyModelFilter(django_filters.FilterSet): name = django_filters.CharFilter(lookup_expr='icontains') class Meta: model = MyModel fields = ['name',] ここで、lookup_expr=‘icontains’は、大文字小文字を区別せずに部分一致を行うための設定です。 次に、作成したフィルタセットをViewSetに適用します: from rest_framework import viewsets from django_filters.rest_framework import DjangoFilterBackend class MyModelViewSet(viewsets.ModelViewSet): queryset = MyModel.objects.all() serializer_class = MyModelSerializer filter_backends = [DjangoFilterBackend] filterset_class = MyModelFilter これで、クライアントからのリクエストにnameパラメータが含まれている場合、その値に部分一致するMyModelのインスタンスがレスポンスとして返されます。 ただし、これらのコードは例示のためのものであり、実際の使用ではモデルやフィールド名を適切に置き換える必要があります。また、セキュリティやパフォーマンスの観点から、適切なフィルタリングとバリデーションを行うことが重要です。

DjangoのModelFormを使用してアップロードしたファイルのパスを取得する

DjangoのModelFormを使用してアップロードしたファイルのパスを取得する

DjangoのModelFormを使用してアップロードしたファイルのパスを取得する機会がありましたのでメモします。 以下のモデルを想定します。 class Document(models.Model): file = models.FileField(upload_to='documents/') 上記に対して、以下のようなviewsで、パスにアクセスすることができました。 from django.shortcuts import render, redirect from .forms import DocumentForm def upload_file(request): if request.method == 'POST': form = DocumentForm(request.POST, request.FILES) if form.is_valid(): document = form.save() file_url = document.file.url # Correct field name used here full_path = document.file.path # Correct field name used here return redirect('some-view') else: form = DocumentForm() return render(request, 'upload.html', {'form': form}) 基本的なことかと思いますが、参考になりましたら幸いです。

DjangoとAWS OpenSearchを接続する

DjangoとAWS OpenSearchを接続する

概要 DjangoとAWS OpenSearchを接続する方法に関するメモです。以下の記事が参考になりました。 https://testdriven.io/blog/django-drf-elasticsearch/ ただし、上記の記事はElasticsearchを対象にした設定のため、OpenSearchに応じた変更が必要です。 変更点 以下のElasticsearch Setupの部分から、OpenSearchに応じた変更が必要でした。 https://testdriven.io/blog/django-drf-elasticsearch/#elasticsearch-setup 具体的には、以下の2つのライブラリが必要でした。 (env)$ pip install opensearch-py (env)$ pip install django-opensearch-dsl その後は、django_elasticsearch_dslとなっている箇所をdjango-opensearch-dslに、elasticsearch_dslをopensearchpyに書き換えることで、記事の通りに進めることができました。 例えば、以下のような形です。 # blog/documents.py from django.contrib.auth.models import User from django_opensearch_dsl import Document, fields # opensearchに変更 from django_opensearch_dsl.registries import registry # opensearchに変更 from blog.models import Category, Article @registry.register_document class UserDocument(Document): class Index: name = 'users' settings = { 'number_of_shards': 1, 'number_of_replicas': 0, } class Django: model = User fields = [ 'id', 'first_name', 'last_name', 'username', ] @registry.register_document class CategoryDocument(Document): id = fields.IntegerField() class Index: name = 'categories' settings = { 'number_of_shards': 1, 'number_of_replicas': 0, } class Django: model = Category fields = [ 'name', 'description', ] @registry.register_document class ArticleDocument(Document): author = fields.ObjectField(properties={ 'id': fields.IntegerField(), 'first_name': fields.TextField(), 'last_name': fields.TextField(), 'username': fields.TextField(), }) categories = fields.ObjectField(properties={ 'id': fields.IntegerField(), 'name': fields.TextField(), 'description': fields.TextField(), }) type = fields.TextField(attr='type_to_string') class Index: name = 'articles' settings = { 'number_of_shards': 1, 'number_of_replicas': 0, } class Django: model = Article fields = [ 'title', 'content', 'created_datetime', 'updated_datetime', ] Populate Elasticsearch Elasticsearchを対象にした上記の記事では、以下のコマンドが紹介されています。 ...

Django REST framework で一括登録する

Django REST framework で一括登録する

概要 Django REST framework で一括登録を行う方法を調べたので、その備忘録です。 以下の記事の通りに進めることで、一括登録用のエンドポイントを作成することができました。 https://qiita.com/Utena-lotus/items/c7bde7f663cfc4aabff1 Postman Postmanで以下のようなリクエストを送りました。 結果、以下のように、一括登録を行うことができました。 まとめ 参考になりましたら幸いです。

djangoでJWTを使う(djangorestframework-simplejwt)

djangoでJWTを使う(djangorestframework-simplejwt)

概要 djangoでJWTを使おうと思い、djangorestframework-jwtを使ってみました。 https://github.com/jpadilla/django-rest-framework-jwt 以下のサイトなどを参考にすすめてみました。 https://dev-yakuza.posstree.com/django/jwt/ ただし、‘rest_framework_jwt.authentication.JSONWebTokenAuthentication’を記述したところで、以下のエラーが発生しました。 ImportError: cannot import name 'smart_text' from 'django.utils.encoding' 調べたところ、以下の記事が見つかりました。 https://stackoverflow.com/questions/72102911/could-not-import-rest-framework-jwt-authentication-jsonwebtokenauthentication かわりにdjangorestframework-simplejwtを使え、とのことでした。 https://github.com/jazzband/djangorestframework-simplejwt 以下、こちらの使い方についてメモを残します。 djangorestframework-simplejwt 以下のページを参考にすることで、動作確認を行うことができました。 https://django-rest-framework-simplejwt.readthedocs.io/en/latest/getting_started.html Postman usernameとpasswordを使って、以下にpostします。 http://localhost:8000/api/token/ 結果、refreshとaccessが得られます。 このaccessのほうの値を使用して、HeaderにAuthorizationを設定して送ります。Bearer [jwt]の形式で送ることで、apiを利用できました。 まとめ djangoでJWTを使う際の参考になりましたら幸いです。

Django REST framework JSON:API(DJA)に独自のモデルのビューをカスタマイズする

Django REST framework JSON:API(DJA)に独自のモデルのビューをカスタマイズする

概要 以下の記事で追加したモデルのビューをカスタマイズしてみます。 sort ordering_fieldsを追加してみます。 ... class UserInfoViewset(ModelViewSet): ordering_fields = ("user_name", ) # ここを追加 queryset = UserInfo.objects.all() serializer_class = UserInfoSerializer def get_object(self): entry_pk = self.kwargs.get("entry_pk", None) if entry_pk is not None: return Entry.objects.get(id=entry_pk).blog return super().get_object() ... 結果、「Filters」の表示で、user_nameのみが選択できるようになりました。 例えば、ageでソートを行うと、validation errorが返却されました。 フィルタ ... class UserInfoViewset(ModelViewSet): queryset = UserInfo.objects.all() serializer_class = UserInfoSerializer ordering_fields = ("user_name", ) # ここから下を追加 # override the default filter backends in order to test QueryParameterValidationFilter # without breaking older usage of non-standard query params like `page_size`. filter_backends = ( QueryParameterValidationFilter, OrderingFilter, DjangoFilterBackend, SearchFilter, ) rels = ( "exact", "iexact", "contains", "icontains", "gt", "gte", "lt", "lte", "in", "regex", "isnull", ) filterset_fields = { "id": ("exact", "in"), "user_name": rels } search_fields = ("user_name", ) ... ... 上記により、以下のようなフィルタが可能になりました。 ...

Django REST framework JSON:API(DJA)に独自のモデルを追加する

Django REST framework JSON:API(DJA)に独自のモデルを追加する

概要 以下の記事で、Django REST framework JSON:API(DJA)の基本的な操作方法を確認しました。 本記事では、DJAに独自のモデルを追加してみます。 参考 以下の記事を参考に、UserInfoモデルを追加してみます。 https://tech-blog.rakus.co.jp/entry/20220329/python 手順 モデルを定義 以下を追記します。 # ユーザ情報を格納する class UserInfo(BaseModel): user_name = models.CharField(verbose_name='ユーザ名',max_length=32) # ユーザ名 birth_day = models.DateField(verbose_name='生年月日') # 生年月日 age = models.PositiveSmallIntegerField(verbose_name='年齢',null=True,unique=False) # 年齢 created_at = models.DateTimeField(verbose_name='作成日時',auto_now_add=True) データベースを構築 以下を実行します。 % django-admin makemigrations --settings=example.settings Migrations for 'example': example/migrations/0013_userinfo.py - Create model UserInfo % django-admin migrate --settings=example.settings Operations to perform: Apply all migrations: auth, contenttypes, example, sessions, sites Running migrations: Applying example.0013_userinfo... OK 参考までに、以下のようなファイルが作成されます。 # Generated by Django 4.1.8 on 2023-06-04 17:35 from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ ("example", "0012_author_full_name"), ] operations = [ migrations.CreateModel( name="UserInfo", fields=[ ( "id", models.AutoField( auto_created=True, primary_key=True, serialize=False, verbose_name="ID", ), ), ("modified_at", models.DateTimeField(auto_now=True)), ("user_name", models.CharField(max_length=32, verbose_name="ユーザ名")), ("birth_day", models.DateField(verbose_name="生年月日")), ("age", models.PositiveSmallIntegerField(null=True, verbose_name="年齢")), ( "created_at", models.DateTimeField(auto_now_add=True, verbose_name="作成日時"), ), ], options={ "abstract": False, }, ), ] コンポーネントの作成 Serializer 以下を追記します。 ...

Django REST framework JSON:API(DJA)を試す

Django REST framework JSON:API(DJA)を試す

概要 Django REST framework JSON:API(DJA)を試す機会がありましたので、その備忘録です。 https://django-rest-framework-json-api.readthedocs.io/en/stable/index.html インストール 以下のページに記載があるexample appを起動します。 https://django-rest-framework-json-api.readthedocs.io/en/stable/getting-started.html git clone https://github.com/django-json-api/django-rest-framework-json-api.git cd django-rest-framework-json-api python3 -m venv env source env/bin/activate pip install -Ur requirements.txt django-admin migrate --settings=example.settings django-admin loaddata drf_example --settings=example.settings django-admin runserver --settings=example.settings 結果、以下の画面などが得られました。 http://localhost:8000 for the list of available collections (in a non-JSON:API format!), http://localhost:8000/swagger-ui/ for a Swagger user interface to the dynamic schema view, or http://localhost:8000/openapi for the schema view’s OpenAPI specification document. ...