NEXT.JS -Integration für Django -Projekte.
Sie möchten also sowohl Django als auch Next.js in Ihrem Projekt verwenden. Es gibt zwei Szenarien:
Sie starten ein neues Projekt und möchten Django als Back-End und Next.js als Front-End verwenden. Django dient nur API -Anfragen. Alle Front-End-Code leben in Next.js und Sie schreiben keine Django-Vorlage.
In diesem Szenario benötigen Sie dieses Paket nicht (obwohl Sie es verwenden können). Sie starten einfach sowohl Django als auch Next.js -Server und weisen Ihren öffentlichen Webserver auf Next.js.
Sie benötigen sowohl Django -Vorlagen als auch Next.js gleichzeitig, und diese Seiten sollten sich leicht miteinander verbinden. Vielleicht haben Sie ein vorhandenes Django -Projekt, bei dem Seiten von Django -Vorlage erstellt wurden und einige neue Seiten in Next.js. Oder Sie möchten Ihr Front-End auf den nächsten.js migrieren, aber da das Projekt groß ist, müssen Sie es allmählich tun.
In diesem Szenario ist dieses Paket genau das Richtige für Sie!
Aus einem Kommentar zum Stackoverflow:
Führen Sie 2 Ports auf demselben Server aus. Eine für Django (öffentlich zugesichts) und eine für Next.js (intern). Lassen Sie Django alle Webanfragen umgehen. Für jede Anfrage werden die HTML -Antwort erhalten. Geben Sie diese genaue HTML -Antwort aus der Django -Ansicht zurück.
Installieren Sie die neueste Version von PYPI.
pip install django-nextjs Fügen Sie django_nextjs.apps.DjangoNextJSConfig zu INSTALLED_APPS hinzu.
Richten Sie je nach Umgebung
Wenn Sie während der Entwicklung Ihre Website unter ASGI bedienen, verwenden Sie Django -Kanäle und fügen Sie NextJSProxyHttpConsumer hinzu, NextJSProxyWebsocketConsumer zu asgi.py wie das folgende Beispiel.
Hinweis: Wir empfehlen die Verwendung von ASGI- und Django -Kanälen, da es für die schnelle Aktualisierung (Heißmodulersatz) erforderlich ist, um in NextJS 12+ ordnungsgemäß zu funktionieren.
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 )),
# ...
}
) Andernfalls (wenn Sie während der Entwicklung unter WSGI dienen) fügen Sie Folgendes zu Beginn von urls.py hinzu:
path ( "" , include ( "django_nextjs.urls" )) Warnung: Wenn Sie unter ASGI dienen, fügen Sie dies nicht zu Ihren urls.py . Es kann Deadlocks verursachen.
Verwenden Sie in der Produktion einen Reverse -Proxy wie Nginx oder Caddy:
| URL | Aktion |
|---|---|
/_next/static/... | Servieren Sie NEXTJS_PATH/.next/static Directory |
/_next/... | Proxy zu http://localhost:3000 |
/next/... | Servieren Sie NEXTJS_PATH/public/next Directory |
Beispielkonfiguration für Nginx:
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";
}
Starten Sie den nächsten.js Server:
# Development:
$ npm run dev
# Production:
$ npm run build
$ npm run startBeginnen Sie mit der Entwicklung Ihrer Seiten in Next.js und definieren Sie dann eine Django -URL für jede nächste Seite. Hier ist ein Beispiel dafür, wie Sie dies tun können:
from django_nextjs . views import nextjs_page
urlpatterns = [
path ( "/nextjs/page" , nextjs_page (), name = "nextjs_page" ),
]Auch wenn es nicht empfohlen wird, müssen Sie manchmal einige benutzerdefinierte Schritte hinzufügen, bevor Sie eine nächste.js -Seite in Django anzeigen. Wir empfehlen jedoch, diese Logik auf die nächsten.js zu verschieben, um sicherzustellen, dass sie auch bei Kunden-Seiten-Weiterleitungen angewendet wird . Wenn Sie sich in dieser Situation befinden, können Sie für jede Seite eine asynchrone Ansicht erstellen, wie unten gezeigt:
from django_nextjs . render import render_nextjs_page
async def jobs ( request ):
# Your custom logic
return await render_nextjs_page ( request )Sie können den HTML -Code ändern, den Next.js in Ihrem Django -Code zurückgibt.
Das Vermeiden von doppelten Code für Navi und Fußzeile ist ein häufiger Anwendungsfall dafür, wenn Sie sowohl die nächsten.js- als auch die Django -Vorlagen verwenden. Ohne sie müssten Sie zwei separate Versionen Ihrer Navigationsleiste und Ihrer Fußzeile (eine Django -Template -Version und eine Next.js -Version) schreiben und verwalten. Sie können jedoch einfach eine Django -Vorlage für Ihre Navigationsleiste erstellen und seinen Code zu Beginn des <body> -Tags einfügen.
Um diese Funktion zu aktivieren, müssen Sie das Dokument- und Root -Layout in Next.js anpassen und die folgenden Anpassungen vornehmen:
id="__django_nextjs_body" als erstes Attribut von <body> Element hinzu.<div id="__django_nextjs_body_begin" /> als erstes Element in <body> .<div id="__django_nextjs_body_end" /> als letztes Element in <body> .HINWEIS: Derzeit funktioniert die HTML -Anpassung nicht mit App Router (Next.js 13+).
Lesen Sie diesen Dokument und passen Sie Ihr nächstes.js -Dokument an:
// 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 >
. . . Schreiben Sie eine Django -Vorlage, die django_nextjs/document_base.html erweitert:
{% 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 %} Übergeben Sie den Vorlagennamen an nextjs_page oder 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 Verzeichnis von Next.js hinzufügen möchten, sollte diese Datei in public/next Unterverzeichnis ordnungsgemäß funktionieren.APPEND_SLASH = False in settings.py Ihres Django -Projekts hinzufügen. Fügen Sie auch am Ende der nächsten Js -Pfade in urls.py nicht / .Standardeinstellungen:
NEXTJS_SETTINGS = {
"nextjs_server_url" : "http://127.0.0.1:3000" ,
"ensure_csrf_token" : True ,
}nextjs_server_url Die URL des nächsten.js -Servers (gestartet von npm run dev oder npm run start )
ensure_csrf_token Wenn der Benutzer kein CSRF -Token hat, stellen Sie sicher, dass eine generiert und in die anfängliche Anforderung an den nächsten.js -Server aufgenommen wird, indem Sie Djangos django.middleware.csrf.get_token aufrufen. Wenn django.middleware.csrf.CsrfViewMiddleware installiert ist, enthält die anfängliche Antwort einen Set-Cookie Header, der den CSRF-Token-Wert auf den Client bestehen muss. Dieses Verhalten ist standardmäßig aktiviert.
ensure_csrf_token ? Möglicherweise müssen Sie GraphQL -Postanfragen zum Abrufen von Daten in Next.js getServerSideProps ausstellen. Wenn dies die erste Anfrage des Benutzers ist, gibt es kein CSRF -Cookie, wodurch die Anforderung fehlschlägt, da GraphQL auch das Abholen von Daten verwendet. Solange getServerSideProps -Funktionen seitdem frei sind (dh keine HTTP-unsicheren Methoden oder GraphQL-Mutationen), sollte dies aus der Sicht der Sicherheit in Ordnung sein. Lesen Sie hier mehr.
pip install -e '.[dev]'pre-commit install . MIT