Next.js Integration para proyectos Django.
Por lo tanto, desea usar Django y Next.js en su proyecto. Hay dos escenarios:
Estás comenzando un nuevo proyecto y desea usar Django como Back-end y Next.js como front-end. Django solo atiende a las solicitudes de API. Todo el código front-end vive en Next.js y no escribes ninguna plantilla de Django.
En este escenario no necesita este paquete (aunque puede usarlo). Simplemente comience los servidores Django y Next.js y apunte su servidor web público a Next.js.
Necesita plantillas de Django y Next.js al mismo tiempo y esas páginas deben vincularse fácilmente entre sí. Tal vez tenga un proyecto Django existente que tiene páginas renderizadas por la plantilla de Django y desee algunas páginas nuevas en Next.js. O desea migrar su front-end a Next.js, pero como el proyecto es grande, debe hacerlo gradualmente.
En este escenario, ¡este paquete es para ti!
De un comentario en StackOverflow:
Ejecute 2 puertos en el mismo servidor. Uno para Django (cara pública) y otra para Next.js (interno). Deje que Django maneje todas las solicitudes web. Para cada solicitud, consulte Next.js desde Django View para obtener la respuesta HTML. Devuelva esa respuesta HTML exacta desde la vista Django.
Instale la última versión de PYPI.
pip install django-nextjs Agregue django_nextjs.apps.DjangoNextJSConfig a INSTALLED_APPS .
Configurar las URL de Next.js dependiendo de su entorno.
Si está sirviendo su sitio en ASGI durante el desarrollo, use los canales Django y agregue NextJSProxyHttpConsumer , NextJSProxyWebsocketConsumer a asgi.py como el siguiente ejemplo.
Nota: Recomendamos usar los canales ASGI y Django, ya que es necesario para la actualización rápida (reemplazo del módulo caliente) para funcionar correctamente en 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 )),
# ...
}
) De lo contrario (si sirve bajo WSGI durante el desarrollo), agregue lo siguiente al comienzo de urls.py :
path ( "" , include ( "django_nextjs.urls" )) ADVERTENCIA: Si está sirviendo bajo ASGI, no agregue esto a sus urls.py . Puede causar muertos muertos.
En producción, use un proxy inverso como Nginx o Caddy:
| Url | Acción |
|---|---|
/_next/static/... | Servir NEXTJS_PATH/.next/static |
/_next/... | Proxy a http://localhost:3000 |
/next/... | Servir NEXTJS_PATH/public/next Directory |
Ejemplo de configuración para 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";
}
Iniciar el servidor Next.js:
# Development:
$ npm run dev
# Production:
$ npm run build
$ npm run startComience desarrollando sus páginas en Next.js, luego defina una URL de Django para cada página Next.js. Aquí hay un ejemplo de cómo puedes hacer esto:
from django_nextjs . views import nextjs_page
urlpatterns = [
path ( "/nextjs/page" , nextjs_page (), name = "nextjs_page" ),
]Aunque no se recomienda, a veces es posible que deba agregar algunos pasos personalizados antes de mostrar una página Next.js en Django. Sin embargo, recomendamos mover esta lógica a Next.js para garantizar que se aplique incluso durante las redireccionamientos del lado del cliente . Si se encuentra en esta situación, puede crear una vista asincrónica para cada página como se demuestra a continuación:
from django_nextjs . render import render_nextjs_page
async def jobs ( request ):
# Your custom logic
return await render_nextjs_page ( request )Puede modificar el código HTML que Next.js devuelve en su código Django.
Evitar el código duplicado para la barra de navegación y el pie de página es un caso de uso común para esto si está utilizando las plantillas Next.js y Django. Sin ella, tendrá que escribir y mantener dos versiones separadas de su barra y pie de página (una versión de plantilla de Django y una versión Next.js). Sin embargo, simplemente puede crear una plantilla de Django para su barra de navegación e insertar su código al comienzo de la etiqueta <body> devuelta de Next.js.
Para habilitar esta función, debe personalizar el documento y el diseño de la raíz en Next.js y hacer los siguientes ajustes:
id="__django_nextjs_body" como el primer atributo del elemento <body> .<div id="__django_nextjs_body_begin" /> como el primer elemento dentro de <body> .<div id="__django_nextjs_body_end" /> como el último elemento dentro de <body> .Nota: Actualmente, la personalización HTML no funciona con App Router (Next.js 13+).
Lea este documento y personalice su documento 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 >
. . . Escriba una plantilla de Django que extienda django_nextjs/document_base.html :
{% 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 %} Pase el nombre de la plantilla a nextjs_page o 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 de Next.js, ese archivo debe estar en el subdirectorio public/next para funcionar correctamente.APPEND_SLASH = False en settings.py de su proyecto django. Además, no agregue / al final de las rutas NextJS en urls.pyConfiguración predeterminada:
NEXTJS_SETTINGS = {
"nextjs_server_url" : "http://127.0.0.1:3000" ,
"ensure_csrf_token" : True ,
}nextjs_server_url La URL del servidor NEXT.JS (iniciado por npm run dev o npm run start )
ensure_csrf_token Si el usuario no tiene un token CSRF, asegúrese de que uno se genere e incluya en la solicitud inicial al Next.JS Server llamando a Django django.middleware.csrf.get_token . Si se instala django.middleware.csrf.CsrfViewMiddleware , la respuesta inicial incluirá un encabezado Set-Cookie para persistir el valor de token CSRF en el cliente. Este comportamiento está habilitado de forma predeterminada.
ensure_csrf_token ? Es posible que deba emitir solicitudes de publicación GraphQL para obtener datos en Next.js getServerSideProps . Si esta es la primera solicitud del usuario, no habrá cookie CSRF, lo que provocará que la solicitud falle ya que GraphQL usa POST incluso para obtener datos. Sin embargo, siempre que las funciones getServerSideProps estén libres de efectos secundarios (es decir, no usan métodos HTTP inseguros o mutaciones GraphQL), esto debería estar bien desde una perspectiva de seguridad. Lea más aquí.
pip install -e '.[dev]'pre-commit install . MIT