ホーム 記事一覧 ブック DH週間トピックス 検索 このサイトについて
English
Drupal: ネストされたフィールドを検索する一例

Drupal: ネストされたフィールドを検索する一例

概要 以下の記事で、Strapiを用いたネストされたフィールドに対する検索方法を調査しました。 今回は同様のことをDrupalで行う方法を調査します。この調査にあたり、以下の記事で、BookとAuthorのコンテンツを登録済みです。 フィルタリングの方法については、以下の記事が参考になりました。 https://www.drupal.org/docs/core-modules-and-themes/core-modules/jsonapi-module/filtering 検索例 以下に対する検索を行います。 /jsonapi/node/book? hobby=danceであるauthorを含むbookの検索 SHORT filter[field_authors.field_hobby]=dance または filter[field_authors.field_hobby][value]=dance NORMAL filter[ex1][condition][path]=field_authors.field_hobby&filter[ex1][condition][value]=dance hobbyにdanを含むauthorを含むbookの検索 SHORT filter[field_authors.field_hobby][operator]=CONTAINS&filter[field_authors.field_hobby][value]=dan NORMAL filter[ex1][condition][path]=field_authors.field_hobby&filter[ex1][condition][operator]=CONTAINS&filter[ex1][condition][value]=dan (参考)hobbyがplayまたはsingであるauthorを含むbookの検索 filter[ex1][condition][path]=field_authors.field_hobby&filter[ex1][condition][operator]=IN&filter[ex1][condition][value][1]=sing&filter[ex1][condition][value][2]=play (参考)Search APIを使う 以下のモジュールを使用することで、複数のコンテンツタイプに対する検索や、フィールド名の指定、ファセットの追加、などができそうです。 https://www.drupal.org/project/jsonapi_search_api 以下の記事で使い方を紹介していますので、参考にしてください。 <https://tech.ldas.jp/ja/posts/8d7aa7c33abffc/#search-api> indexの作成 例えば、Search APIのindexとして、以下のように設定します。 これにより、以下のURLからもbookの情報が得られます。 /jsonapi/index/book 通常のjsonapi(/jsonapi/node/bookなど)と比較して、metaという項目にcountが含まれることで、検索結果の全数が確認できます。(通常のjsonapiでも追加する方法があるかもしれませんが、調査不足により不明です。) { "jsonapi": { "version": "1.0", "meta": { "links": { "self": { "href": "http://jsonapi.org/format/1.0/" } } } }, "data": [...], "meta": { "count": 4 }, "links": { "self": { "href": "https://xxx/jsonapi/index/book" } } } フィルタリング また、「hobby=danceであるauthorを含むbookの検索」については、先のindex作成において、Property path「field_authors:entity:field_hobby」をMachine name「field_hobby」に割り当てましたので、以下のシンプルなクエリで実行できました。 SHORT filter[field_hobby]=dance NORMAL filter[ex1][condition][path]=field_hobby&filter[ex1][condition][value]=dance ファセット さらに、(本記事執筆時点での不確かな知識において、)Search APIを使用する大きな利点の一つとして、facetsが使用できるようになる点が挙げられます。 { "facets": [ { "id": "field_hobby", "label": "authors » Content » hobby", "path": "field_hobby", "terms": [ { "url": "https://xxx/jsonapi/index/book?filter%5Bfield_hobby-facet%5D%5Bcondition%5D%5Bpath%5D=field_hobby&filter%5Bfield_hobby-facet%5D%5Bcondition%5D%5Boperator%5D=IN&filter%5Bfield_hobby-facet%5D%5Bcondition%5D%5Bvalue%5D%5B0%5D=dance&filter%5Bfield_hobby-facet%5D%5Bcondition%5D%5Bvalue%5D%5B1%5D=play", "values": { "value": "play", "label": "play", "active": false, "count": 1 } }, { "url": "https://xxx/jsonapi/index/book?filter%5Bfield_hobby-facet%5D%5Bcondition%5D%5Bpath%5D=field_hobby&filter%5Bfield_hobby-facet%5D%5Bcondition%5D%5Boperator%5D=IN&filter%5Bfield_hobby-facet%5D%5Bcondition%5D%5Bvalue%5D%5B0%5D=dance&filter%5Bfield_hobby-facet%5D%5Bcondition%5D%5Bvalue%5D%5B1%5D=sing", "values": { "value": "sing", "label": "sing", "active": false, "count": 1 } }, { "url": "https://xxx/jsonapi/index/book?filter%5Bfield_hobby%5D=dance", "values": { "value": "dance", "label": "dance", "active": true, "count": 2 } } ] } ] } まとめ 不正確な情報もあるかもしれませんが、Drupalでのnested構造に対する検索と、JSON:APIとSearch APIの組み合わせについて、参考になりましたら幸いです。 ...

Drupal: Feedsを用いた一括登録と更新の例

Drupal: Feedsを用いた一括登録と更新の例

概要 以下の記事で、Strapiを用いたネストされたフィールドに対する検索方法を調査しました。 今回は同様のことをDrupalで行うにあたり、その準備である、コンテンツの一括登録及び更新方法に関する備忘録です。上記の記事と類似の構造を設定するために、BookとAuthorという2つのコンテンツタイプを対象にします。 content typeの作成 BookとAuthorのcontent typeを作成します。 Author 以下、Authorの例です。 id, name, hobbyというフィールドを作成します。feedsは後から追加されるものなので無視してください。 Book Bookのフィールドとして、authorsを作成し、Cotentをフィールドとして選択します。 Reference typeのcontent typeとしてAuthorを選択しました。 feedsの設定 一括登録のための設定を行います。 Author 以下にアクセス /admin/structure/feeds csvをアップロードして登録するため、以下のように設定します。 フィールドNAMEとHOBBYを以下のように設定します。titleは必須項目としていたため、設定しています。またifをUniqueな項目としています。 Book Bookに関する注意点として、authorsは他のコンテンツタイプのidを指定するようにしています。具体的には、以下の図のように、Reference byに「node.field_id」を指定しています。 feedsによる一括登録 /admin/content/feed Author 先に作成したcsvファイルアップロードすることで、以下のように登録が完了します。 Book authorsに正しくcontent typeがauthorのコンテンツが紐付けられています。 (参考)Feedsを用いた更新 authorのfeeds設定を設定するために、以下にアクセス /admin/structure/feeds/manage/author?destination=/admin/structure/feeds 以下のように、「Update existing content items」で「Update existing content items」とすることで、更新を行うことができました。「field_id」をUniqueとしたため、この値に基づいて、新規・更新が判定されます。 ! 「Replace existing content items」や「Update existing content items」などの挙動の違いを十分に理解できていないため、使用される際は検証の上、ご利用ください。 まとめ Feedsを用いた一括登録と更新、および異なるコンテンツタイプとの関連付けを行いました。参考になりましたら幸いです。

Drupal: カスタムモジュールを用いて、コンテンツタイプとフィールドを追加する

Drupal: カスタムモジュールを用いて、コンテンツタイプとフィールドを追加する

概要 Drupalのカスタムモジュールを用いて、コンテンツタイプとフィールドを追加する方法の備忘録です。 以下の2つの記事が参考になりました。 https://www.drupal.org/docs/drupal-apis/entity-api/creating-a-custom-content-type-in-drupal-8 https://www.digitalnadeem.com/drupal/how-to-create-content-type-fields-and-view-while-installing-custom-module-in-drupal-9-using-configuration-manager/ Car Brandの例 先に紹介した一つ目の記事の通り進めると、コンテンツタイプ「Car Brand」、フィールド「body」を追加することができました。 なお、上記の記事ではカスタムモジュールの作成の部分がスキップされています。まずはじめに以下のようなフォルダ、およびファイルを作成します。 name: foobar description: サンプルモジュール package: Custom type: module version: 1.0 core_version_requirement: ^8 || ^9 独自のフィールドの追加 上記を参考に、コンテンツタイプを追加することができましたが、独自のフィールドを追加するには、Fieldに加えて、Field storageというものも追加する必要がありました。 このField storageのymlの記述方法がわからなかった際に、冒頭で紹介した2つ目のリンクである、以下の記事が参考になりました。 https://www.digitalnadeem.com/drupal/how-to-create-content-type-fields-and-view-while-installing-custom-module-in-drupal-9-using-configuration-manager/ モジュール「Configuration Manager」を使うことで、すでに登録済みのFieldやField storageの定義内容を確認することができました。 上記を踏まえて、IIIF Mediaというコンテンツタイプを作成して、iiif_image_urlという文字列を格納するフィールドと、iiif_image_widthとiiif_image_heightという数値を格納するフィールドを作成してみます。以下のようなファイルが必要です。 コンテンツタイプ modules/custom/foobar/config/install/node.type.iiif_media.yml # node.type.iiif_media.yml langcode: en status: true dependencies: enforced: module: - foobar # This is the name of the module we're using for this example name: 'IIIF Media' type: iiif_media description: 'Content type for IIIF Media' help: '' new_revision: false preview_mode: 1 display_submitted: true フィールド:iiif_image_url(string) Field storage modules/custom/foobar/config/install/field.storage.node.field_iiif_image_url.yml ...

Drupal: 異なるコンテンツタイプのコンテンツを相互にリンクさせる

Drupal: 異なるコンテンツタイプのコンテンツを相互にリンクさせる

概要 異なるコンテンツタイプのコンテンツを相互にリンクさせる方法を調べたので、その備忘録です。 具体的には、以下のitem 1がimage 1というコンテンツをiiif_image2というフィールドを介してつながっています。 上記に対して、image 1というページに、item 1へのリンクを設けることが目的です。 この実現にあたり、以下の記事を参考にしました。 https://drupal.stackexchange.com/questions/255447/view-for-entity-reference-reverse-backwards-forwards 方法 ビューの追加 /admin/structure/views に移動し、 +ビューを追加 「Create a block」オプションをチェックします ビューの設定 次のページで、Advancedの設定を行います。 リレーションシップ field_iiif_image2のリレーションシップを追加します。これは、2つのコンテンツタイプを関連付けるために重要です。 Require this relationshipにチェックを入れる必要があります。このフィールドを持たない場合には表示しない、という挙動になるものと理解しました。 コンテキストフィルター 次に、現在のコンテンツタイプのランディングページにコンテキストフィルターを追加します。このようにして、ビューで使用される実際のノードIDを取得します。これで、field_iiif_image2で同じノードIDを持つページのみを見つけることができます。 IDで探す(コンテンツ) デフォルト値を提供-> URL からのコンテンツ IDにチェックを入れます 次のような結果になります。 Update previewの箇所で、メディアのノードID(ここでは、62602)を入力してみます。本メディアが参照されているアイテムへのリンクが表示されます。 ブロックの追加 以下にアクセスします。 /admin/structure/block 例えば、「Content」の横の「Place block」ボタンを押します。 /node/*に配置してみます。 結果、冒頭のように、当該imageが属するitemを表示することができます。 まとめ 使用している用語に統一性がなく、わかりにくい点が多く恐縮ですが、参考になりましたら幸いです。

Drupal: カスタムRESTリソースを作成する

Drupal: カスタムRESTリソースを作成する

概要 以下を参考に、カスタムRESTリソースを作成しました。 https://www.drupal.org/docs/drupal-apis/restful-web-services-api/custom-rest-resources 上記の記事の通り進めることで、以下のURLから、JSONの結果を得ることができました。 /demo_rest_api/demo_resource { "message": "Hello, this is a rest service" } REST UIモジュール 上記の記事において、以下の記載がありました。 If you are using the REST UI contrib module, you should now be able to see it in the list of available endpoints and you should be able to configure the GET method. この点については、以下の記事を参考に、REST UIモジュールを有効化しました。 https://www.studio-umi.jp/blog/12/357 IIIF Presentation APIの試作 次に、コンテンツ毎にJSON作成に取り組みます。具体的には、/iiif/3/{id}/manifestというパスにアクセスすると、IIIF Presentation API v3に基づく情報を出力するようにしてみます。 以下の記事が参考になりました。 https://medium.com/drupaljournal/create-custom-rest-resource-for-get-and-post-method-in-drupal-8-e445330be3ff 以下のようなファイルを作成します。以下の例では、とりあえず$nodeからtitleを取得しています。これを応用することで、他のフィールドの情報も取得することができそうです。 <?php namespace Drupal\demo_rest_api\Plugin\rest\resource; use Drupal\node\Entity\Node; use Drupal\node\NodeInterface; use Drupal\rest\Plugin\ResourceBase; use Drupal\rest\ResourceResponse; /** * Annotation for get method * * @RestResource( * id = "iiif_presentation_3", * label = @Translation("IIIF Presentation API v3"), * uri_paths = { * "canonical" = "/iiif/3/{id}/manifest" * } * ) */ class Presentation3 extends ResourceBase { /** * Responds to GET requests. It will return serialize json format of node * object. * * @param $id * Node id. */ public function get($id) { if ($id) { // Load node $node = Node::load($id); if ($node instanceof NodeInterface) { $manifest = [ "@context" => "http://iiif.io/api/presentation/3/context.json", "type" => "Manifest", "label" => [ "none" => [ $node->get("title")[0]->get("value")->getValue() ] ] ]; $response = new ResourceResponse($manifest); // Configure caching for results if ($response instanceof CacheableResponseInterface) { $response->addCacheableDependency($node); } return $response; } return new ResourceResponse('Article doesn\'t exist', 400); } return new ResourceResponse('Article Id is required', 400); } } パーミッションの許可 以下のページで、Anonymous userにチェックを入れて、外部からのアクセスを許可します。 ...

DrupalのRESTful Viewsを使ってカスタムAPIを作成する

DrupalのRESTful Viewsを使ってカスタムAPIを作成する

概要 以下の記事を参考に、DrupalのRESTful Viewsを使ってカスタムAPIを作成したので、その備忘録です。 https://acret.jp/drupal/node/434 上記の記事の内容に加えて、ページネーションに関する設定方法も記載しています。 Viewsの作成 上記のサイトの通りに進めました。 ページネーションを許可する 以下の記事を参考にしました。 https://www.drupal.org/forum/support/post-installation/2015-12-04/rest-export-pagination ViewsのPagerを選択します。以下の通り、Fullとしました。Miniでも大丈夫そうでした。 「Allow user to control the number of items displayed in this view」と「Allow user to specify number of items skipped from beginning of this view.」にチェックを入れます。 結果、以下のようなパラメータが使えるようになりました。 /my_custom_api?items_per_page=10 /my_custom_api?items_per_page=10&offset=1 /my_custom_api?items_per_page=50 まとめ カスタムAPIを作成する際の参考になりましたら幸いです。

Drupalのビューで結果の合計数を表示する

Drupalのビューで結果の合計数を表示する

概要 Drupalのビューで結果の合計数を表示する方法を調べたので、その備忘録です。以下のように、検索結果の合計数などが表示されます。 方法 以下の記事を参考にしました。 https://ostraining.com/blog/drupal/count-views/ 以下のページにアクセス /admin/structure/views/view/content Header横のAddボタンを押す Result summaryを選択 Applyを押して、Saveを押します。 まとめ 参考になりましたら幸いです。

Next.js for DrupalにおけるDrupal Search APIを用いた検索(ファセット検索など)

Next.js for DrupalにおけるDrupal Search APIを用いた検索(ファセット検索など)

概要 Next.js for Drupalを試してみました。 https://next-drupal.org/ 以下の「Get Started」の通りにすすめることで、Next.jsとDrupalを連携させることができました。 https://next-drupal.org/learn/quick-start また、以下の記事で、ファセット検索の実装例が紹介されています。 https://next-drupal.org/guides/search-api 本記事では、特に後者のファセット検索の実現に関する備忘録です。 Search API 以下、Serverとindexを作成します。 公式サイトでは以下が参考になります。 https://www.drupal.org/docs/contributed-modules/search-api 日本語サイトでは以下が参考になります。 https://www.acquia.com/jp/blog/introduction-to-search-api-1 Serverの作成 indexの作成 今回、test_index_20230417というインデックスを作成します。 さらに、タイトルをフィールドとして追加しました。 その後、インデクシングを行います。 JSON:API 上記を行ったところで、キャッシュをクリアします。 /admin/config/development/performance その後、以下のURLからエンドポイントにアクセスできるようになります。 /jsonapi/index/test_index_20230417 以下のようなクエリパラメータによって、検索結果の絞り込みができます。 /jsonapi/index/test_index_20230417?filter[title]=更新したタイトル { "jsonapi": { "version": "1.0", "meta": { "links": { "self": { "href": "http://jsonapi.org/format/1.0/" } } } }, "data": [ { "type": "node--service", "id": "82a34c35-f1b7-49eb-81ac-f15d0deac22c", "links": { "self": { "href": "https://xxx/jsonapi/node/service/82a34c35-f1b7-49eb-81ac-f15d0deac22c?resourceVersion=id%3A5075" } }, "attributes": { "drupal_internal__nid": 4, "drupal_internal__vid": 5075, "langcode": "en", "revision_timestamp": "2023-04-12T08:19:00+00:00", "revision_log": null, "status": true, "title": "更新したタイトル", "created": "2023-04-11T02:09:35+00:00", "changed": "2023-04-12T08:19:00+00:00", "promote": false, "sticky": false, "default_langcode": true, "revision_translation_affected": true, ... Facets 以下にアクセスします。 ...

Drupalのコンテンツの一括削除の方法

Drupalのコンテンツの一括削除の方法

概要 Drupalのコンテンツの一括削除の方法を調べたので、その備忘録です。以下の記事が参考になりました。 https://www.webwash.net/how-to-bulk-delete-content-in-drupal/ 以下の3つの方法が紹介されていました。 Drupal コア UI の使用 (Using Drupal Core UI) Drush の使用 (Using Drush) ビューの一括操作 (VBO) の使用 (Using Drupal Views Bulk Operations (VBO)) Drupal コア UI の使用 以下、日本語訳です。 小さな Drupal サイトがあり、削除するノードが約 300 未満の場合は、この方法を使用する必要があります。これは、Drupal コアの UI を使用すると、デフォルトで一度に 50 ノードしか削除できないためです。サイトが大きくなると、これは面倒になります。 Drush の使用 以下、日本語訳です。 コマンド ラインを使用すると、Drush を使用できます。これが推奨される方法です。 例えば以下では、記事コンテンツ タイプのすべてのノードを削除します。 drush entity:delete node --bundle=article ただ、上記のサイトにも記載がありましたが、PHP メモリ制限にひっかかることがあるようです。Amazon Lightsail上に立てた512MBメモリの環境において、5,000件のコンテンツの一括削除を試みたところ、以下のように制限に引っかかってしまいました。ただし、再度同じコマンドを実行することで、無事に一括削除ができました。 drush entity:delete node --bundle=article 2550/5057 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓░░░░░░░░░░░░░░] 50% PHP Fatal error: Allowed memory size of 268435456 bytes exhausted (tried to allocate 20480 bytes) in /opt/bitnami/drupal/core/lib/Drupal/Core/TypedData/Plugin/DataType/ItemList.php on line 76 PHP Fatal error: Allowed memory size of 268435456 bytes exhausted (tried to allocate 32768 bytes) in /opt/bitnami/drupal/vendor/symfony/http-foundation/Response.php on line 895 specify the chunk/batch size デフォルトでは50件ずつ処理されますが、–chunks=100のように引数を加えることで、バッチサイズを変更できました。 ...

DrupalとAmazon OpenSearch Serviceを接続する

DrupalとAmazon OpenSearch Serviceを接続する

概要 DrupalとAmazon OpenSearch Serviceを接続する機会がありましたので、その備忘録です。以下の記事が参考になりました。 https://www.acquia.com/jp/blog/intergration-with-drupal-and-elasticsearch モジュールのインストール drupal/search_apiとdrupal/elasticsearch_connectorに加えて、nodespark/des-connectorをインストールする必要がありました。 (バージョンの指定方法など、改善の余地があるかもしれません。) composer require "nodespark/des-connector:^7.x-dev" composer require 'drupal/search_api:^1.29' composer require "drupal/elasticsearch_connector ^7.0@alpha" 続けて、以下で有効化します。 drush pm:enable search_api elasticsearch_connector DrupalをElasticsearchに接続する クラスタ 以下にアクセス /admin/config/search/elasticsearch-connector 「Add cluster」をクリックします。 そして、以下のように値を入力します。Amazon OpenSearch ServiceでBasic認証をかけている方法を前提としています。注意点として、「Server URL」に入力する値の末尾に、:443が必要でした。 Elasticsearchサーバーへの接続が成功すると、Cluster Statusに yellow や green と表示されます。 インデックス 次に、任意の作業ですが、インデックスを作成します。「Add index」ボタンを押して、nameだけ入力してみます。結果、以下のようにインデックスが作成されました。 Search APIの設定 今度は、Search API側の設定を行います。以下にアクセスします。 /admin/config/search/search-api サーバの追加 「Add Server」ボタンを押します。特に、BackendにElasticsearchを選択して、Clusterに先程作成したクラスタを選択します。 インデックスの追加 以下の画面には出ていませんが、「Datasources」のところで、「Content」を選択しています。また「Server」で、上記で作成したサーバを選択しています。 次に、末尾の「Save and add fields」ボタンをクリックします。 フィールドの追加 今回は最低限のフィールドとして、Titleを追加しておきます。 追加したフィールドに対するFulltext検索を可能とするために、「Type」を変更します。これらの設定は適宜変更してください。 再インデクシング 「Save changes」を押すと、以下のように、reindexingへのリンク(黄色)が表示されます。 ...

DrupalでGraphQLを試す

DrupalでGraphQLを試す

概要 DrupalでGraphQLを試してみましたので、その備忘録です。以下の文書が参考になりました。 https://drupal-graphql.gitbook.io/graphql/ Amazon LightsailにインストールされたDrupalを前提とします。 モジュールのインストール 以下のモジュールをインストールします。 https://www.drupal.org/project/graphql ただし、以下のモジュールを事前にインストールする必要がありました。 https://www.drupal.org/project/typed_data 結果、以下により、インストールができました。 cd /home/bitnami/stack/drupal composer require 'drupal/typed_data:^1.0@beta' composer require 'drupal/graphql:^4.4' GUIからのモジュールインストール 関連する以下の3つのモジュール全てにチェックを入れて、インストールしました。 設定 以下にアクセスします。 /admin/config/graphql 「Create server」で、以下のように設定しました。test_serverという名前にしました。 Explore 以下にアクセスします。 /admin/config/graphql/servers/manage/test_server/explorer 以下のような画面に遷移します。 以下のクエリを投げてみます。 { articles { total } } 以下のような結果が得られます。 { "data": { "articles": { "total": 5054 } } } まとめ 今後、独自のスキーマを用いた使用方法についても調査してみたいと思います。参考になりましたら幸いです。

Pythonを使ってDrupalのタクソノミーの登録とコンテンツへの追加

Pythonを使ってDrupalのタクソノミーの登録とコンテンツへの追加

概要 以下のシリーズの続きです。 今回は、タクソノミーの登録とコンテンツへの追加を行います。 タクソノミーの登録 事前に、ne_classというタクソノミーをGUIを通じて作成しました。以下のようなURLで一覧できます。 /jsonapi/taxonomy_term/ne_class 以下、新しいタクソノミーを登録するプログラムです。host, username, passwordは適宜設定してください。 payload = { "data": { "type": "taxonomy_term--ne_class", "attributes": { "name": "干瀬", } } } _type = "ne_class" url = f"{host}/jsonapi/taxonomy_term/{_type}" r = requests.post(url, headers=headers, auth=(username, password), json=payload) r.json() 以下のような結果が得られます。 {'jsonapi': {'version': '1.0', 'meta': {'links': {'self': {'href': 'http://jsonapi.org/format/1.0/'}}}}, 'data': {'type': 'taxonomy_term--ne_class', 'id': '17c70bd6-e6fc-46e2-bb5d-2377ba9c8ab8', ... コンテンツへの追加 事前に、PlaceというコンテンツタイプをGUIを通じて作成しました。また、field_ne_classを作成して、上記のタクソノミーne_classを値の候補として設定しました。 relationshipsのidに先程取得したタクソノミーのidを指定しています。 payload = { "data": { "type": "node--place", "attributes": { "title": "xxx" }, "relationships": { "field_ne_class": { "data": { "type": "taxonomy_term--ne_class", "id": "17c70bd6-e6fc-46e2-bb5d-2377ba9c8ab8", } } } } } _type = "place" url = f"{host}/jsonapi/node/{_type}" r = requests.post(url, headers=headers, auth=(username, password), json=payload) r.json() まとめ タクソノミーの追加やコンテンツへの関連付けも機械的に行うことができそうです。他のよりよい方法もあるかと思いますが、参考になりましたら幸いです。 ...

Pythonを使ってDrupalのコンテンツを更新・削除する

Pythonを使ってDrupalのコンテンツを更新・削除する

概要 以下の記事で、コンテンツの新規登録の方法を記載しました。 今回は、既存のコンテンツの更新・削除を試みます。 アイテムの絞り込み 以下のようなプログラムにより、登録済みのコンテンツを取得することができます。今回は、titleが「更新前のタイトル」のコンテンツを取得しました。res["data"]は配列になります。 username = "xxx" password = "xxx" host = "xxx" query = { "title": "更新前のタイトル" } item_type = "article" filters = [] for key, value in query.items(): filters.append(f'filter[{key}]={value}') filter_str = '&'.join(filters) endpoint = f'{host}/jsonapi/node/{item_type}?{filter_str}' r = requests.get(endpoint, headers=headers, auth=(username, password)) res = r.json() len(res['data']) 更新対象のコンテンツのID取得 730f844d-b476-4485-8957-c33fccb7f8acのようなIDが得られます。 item = res['data'][0] item_id = item['id'] 更新 typeとidを指定して更新します。 ...

Pythonを使ってDrupalにコンテンツを追加する

Pythonを使ってDrupalにコンテンツを追加する

概要 Pythonを使ってDrupalにコンテンツを追加する機会がありましたので、その備忘録です。以下の記事を参考にしました。 https://weimingchenzero.medium.com/use-python-to-call-drupal-9-core-restful-api-to-create-new-content-9f3fa8628ab4 Drupalの準備 Amazon Lightsailに作成しました。以下の記事などが参考になります。 https://annai.co.jp/article/use-aws-lightsail モジュール 以下をインストールします。 HTTP Basic Auth JSON:API RESTful Web Services Serialization JSON:APIの設定変更 以下にアクセスして、設定を変更します。 </admin/config/services/jsonapi> Python {ipアドレス or ドメイン名}、{パスワード}を適宜設定してください。 Amazon Lightsailの場合、初期ユーザ名はuserです。またパスワードは以下のコマンドで確認します。 cat ~/bitnami_application_password import requests from requests.auth import HTTPBasicAuth endpoint = 'http://{ipアドレス or ドメイン名}/jsonapi/node/article' u = 'user' p = '{パスワード}' headers = { 'Accept': 'application/vnd.api+json', 'Content-Type': 'application/vnd.api+json' } payload = { "data": { "type": "node--article", "attributes": { "title": "What's up from Python", "body": { "value": "Be water. My friends.", "format": "plain_text" } } } } r = requests.post(endpoint, headers=headers, auth=(u, p), json=payload) r.text その他 以下のようにnote_typeの登録も試みました。 payload = { "data": { "type": "node_type--node_type", "attributes": { "title": "テスト", "description": "node_typeのテストです。" } } } url = f"{host}/jsonapi/node_type/node_type" r = requests.post(url, headers=headers, auth=(username, password), json=payload) r.json() 結果、以下のように、Method Not Allowedとなりました。 ...