Djangoプロジェクトのnext.js統合。
したがって、プロジェクトでdjangoとnext.jsの両方を使用したいと考えています。 2つのシナリオがあります。
新しいプロジェクトを開始しており、Djangoをバックエンドとして、Next.jsをフロントエンドとして使用したいと考えています。 DjangoはAPIリクエストのみを提供します。すべてのフロントエンドコードはnext.jsに存在し、djangoテンプレートを書きません。
このシナリオでは、このパッケージは必要ありません(ただ使用できますが)。 Djangoとnext.jsサーバーの両方を開始し、public Webserverをnext.jsに向けてください。
djangoテンプレートとnext.jsの両方が同時に必要で、それらのページは互いに簡単にリンクする必要があります。たぶん、あなたはdjangoテンプレートによってレンダリングされたページがあり、next.jsにいくつかの新しいページが必要な既存のDjangoプロジェクトを持っています。または、フロントエンドをnext.jsに移行したいのですが、プロジェクトが大きいため、徐々に行う必要があります。
このシナリオでは、このパッケージはあなたのためです!
Stackoverflowに関するコメントから:
同じサーバーで2つのポートを実行します。 1つはDjango(Public Facing)、もう1つはNext.js(内部)用です。 DjangoがすべてのWebリクエストを処理させます。各リクエストについて、HTML応答を取得するために、Django Viewのnext.jsをクエリします。 Djangoビューからその正確なHTML応答を返します。
Pypiから最新バージョンをインストールします。
pip install django-nextjs django_nextjs.apps.DjangoNextJSConfigをINSTALLED_APPSに追加します。
環境に応じてnext.js URLをセットアップします。
開発中にASGIでサイトを提供している場合は、Djangoチャンネルを使用して、次の例のようにasgi.pyにNextJSProxyHttpConsumer NextJSProxyWebsocketConsumer追加します。
注: ASGIチャンネルとDjangoチャンネルを使用することをお勧めします。これは、Fast Refresh(Hot Moduleの交換)がNextJS 12+で適切に動作するために必要であるためです。
import os
from django . core . asgi import get_asgi_application
from django . urls import re_path , path
os . environ . setdefault ( "DJANGO_SETTINGS_MODULE" , "myproject.settings" )
django_asgi_app = get_asgi_application ()
from channels . auth import AuthMiddlewareStack
from channels . routing import ProtocolTypeRouter , URLRouter
from django_nextjs . proxy import NextJSProxyHttpConsumer , NextJSProxyWebsocketConsumer
from django . conf import settings
# put your custom routes here if you need
http_routes = [ re_path ( r"" , django_asgi_app )]
websocket_routers = []
if settings . DEBUG :
http_routes . insert ( 0 , re_path ( r"^(?:_next|__next|next).*" , NextJSProxyHttpConsumer . as_asgi ()))
websocket_routers . insert ( 0 , path ( "_next/webpack-hmr" , NextJSProxyWebsocketConsumer . as_asgi ()))
application = ProtocolTypeRouter (
{
# Django's ASGI application to handle traditional HTTP and websocket requests.
"http" : URLRouter ( http_routes ),
"websocket" : AuthMiddlewareStack ( URLRouter ( websocket_routers )),
# ...
}
)それ以外の場合(開発中にWSGIの下で提供する場合)、 urls.pyの先頭に以下を追加します:
path ( "" , include ( "django_nextjs.urls" ))警告: ASGIで提供している場合は、これをurls.pyに追加しないでください。デッドロックを引き起こす可能性があります。
生産では、NginxやCaddyのような逆プロキシを使用してください。
| URL | アクション |
|---|---|
/_next/static/... | NEXTJS_PATH/.next/staticディレクトリを提供します |
/_next/... | http://localhost:3000へのプロキシ |
/next/... | NEXTJS_PATH/public/nextディレクトリを提供します |
nginxの例Config:
location /_next/static/ {
alias NEXTJS_PATH/.next/static/;
expires max;
add_header Cache-Control "public";
}
location /_next/ {
proxy_pass http://127.0.0.1:3000;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location /next/ {
alias NEXTJS_PATH/public/next/;
expires max;
add_header Cache-Control "public";
}
next.jsサーバーを開始します:
# Development:
$ npm run dev
# Production:
$ npm run build
$ npm run startnext.jsでページを開発することから始めて、次に、next.jsページごとにdjango URLを定義します。これがどのようにこれを行うことができるかの例です:
from django_nextjs . views import nextjs_page
urlpatterns = [
path ( "/nextjs/page" , nextjs_page (), name = "nextjs_page" ),
]推奨されていませんが、Djangoにnext.jsページを表示する前に、いくつかのカスタムステップを追加する必要がある場合があります。ただし、クライアント側のリダイレクト中でも適用されるように、このロジックをNext.jsに移動することをお勧めします。この状況にいる場合は、以下に示すように、各ページの非同期ビューを作成できます。
from django_nextjs . render import render_nextjs_page
async def jobs ( request ):
# Your custom logic
return await render_nextjs_page ( request )next.jsがdjangoコードで返すHTMLコードを変更できます。
next.jsとdjangoテンプレートの両方を使用している場合、Navbarとフッターの重複コードを回避することは、このための一般的なユースケースです。それがなければ、Navbarとフッターの2つの別々のバージョン(Djangoテンプレートバージョンとnext.jsバージョン)を書き込み、維持する必要があります。ただし、Navbar用のDjangoテンプレートを作成して、next.jsから返された<body>タグの先頭にコードを挿入するだけです。
この機能を有効にするには、next.jsでドキュメントとルートレイアウトをカスタマイズし、次の調整を行う必要があります。
id="__django_nextjs_body"を<body>要素の最初の属性として追加します。<div id="__django_nextjs_body_begin" /> <body>追加します。<div id="__django_nextjs_body_end" />追加<body>に追加します。注:現在、HTMLカスタマイズはApp Router(Next.js 13+)で動作していません。
このドキュメントを読んで、next.jsドキュメントをカスタマイズします。
// pages/_document.jsx (or .tsx)
...
< body id = "__django_nextjs_body" >
< div id = "__django_nextjs_body_begin" />
< Main />
< NextScript />
< div id = "__django_nextjs_body_end" />
</ body >
. . . django_nextjs/document_base.htmlを拡張するdjangoテンプレートを書きます:
{% extends "django_nextjs/document_base.html" %}
{% block head %}
<!-- ... the content you want to place at the beginning of "head" tag ... -->
{{ block.super }}
<!-- ... the content you want to place at the end of "head" tag ... -->
{% endblock %}
{% block body %}
... the content you want to place at the beginning of "body" tag ...
... e.g. include the navbar template ...
{{ block.super }}
... the content you want to place at the end of "body" tag ...
... e.g. include the footer template ...
{% endblock %}テンプレート名をnextjs_pageまたはrender_nextjs_pageに渡す:
from django_nextjs . render import render_nextjs_page
from django_nextjs . views import nextjs_page
async def jobs ( request ):
return await render_nextjs_page ( request , template_name = "path/to/template.html" )
urlpatterns = [
path ( "/nextjs/page" , nextjs_page ( template_name = "path/to/template.html" ), name = "nextjs_page" ),
path ( "/jobs" , jobs , name = "jobs_page" )
]publicディレクトリにファイルを追加する場合は、そのファイルがpublic/nextサブディレクトリに正しく機能する必要があります。settings.pyにAPPEND_SLASH = Falseを追加する必要がある場合があります。また、 urls.pyのnextjsパスの最後に追加/しないでください。デフォルト設定:
NEXTJS_SETTINGS = {
"nextjs_server_url" : "http://127.0.0.1:3000" ,
"ensure_csrf_token" : True ,
}nextjs_server_url next.jsサーバーのURL( npm run devまたはnpm run startによって開始)
ensure_csrf_tokenユーザーがCSRFトークンを持っていない場合は、djangoのdjango.middleware.csrf.get_tokenを呼び出すことにより、生成され、next.jsサーバーへの最初の要求に含まれていることを確認してください。 django.middleware.csrf.CsrfViewMiddlewareがインストールされている場合、最初の応答には、クライアントにCSRFトークン値を持続するためのSet-Cookieヘッダーが含まれます。この動作はデフォルトで有効になります。
ensure_csrf_token必要があるのはいつですか? next.js getServerSidePropsでデータを取得するためにGraphQL POSTリクエストを発行する必要がある場合があります。これがユーザーの最初のリクエストである場合、CSRF Cookieはありません。GraphQLはデータフェッチの場合でも投稿を使用するため、リクエストが失敗します。ただし、 getServerSideProps関数が副作用フリーである限り(つまり、HTTP UnsafeメソッドやGraphQL変異を使用しない)、これはセキュリティの観点からは問題ありません。詳細はこちらをご覧ください。
pip install -e '.[dev]'pre-commit installフックをインストールします。 mit