Next.js Integration для проектов Django.
Таким образом, вы хотите использовать и Django, и Next.js в вашем проекте. Есть два сценария:
Вы начинаете новый проект, и вы хотите использовать Django в качестве Back-end и Next.js в качестве фронта. Джанго обслуживает только запросы API. Весь фронт-код живет в next.js, и вы не пишете ни одного шаблона Django.
В этом сценарии вам не нужен этот пакет (хотя вы можете его использовать). Вы просто начинаете и Django, и Next.js Servers и указываете свой публичный веб -сервер на next.js.
Вам нужны и шаблоны Django, и Next.js одновременно, и эти страницы должны легко связаться друг с другом. Может быть, у вас есть существующий проект Django, на котором страницы, представленные Template Django, и вы хотите несколько новых страниц на letle.js. Или вы хотите перенести свой фронт-end на next.js, но, поскольку проект большой, вам нужно делать это постепенно.
В этом сценарии этот пакет для вас!
Из комментария на Stackoverflow:
Запустите 2 порта на том же сервере. Один для Джанго (публичный лицо) и один для следующего.js (внутренний). Позвольте Джанго обрабатывать все веб -запросы. Для каждого запроса, запросите Next.js от Django View, чтобы получить ответ HTML. Верните этот точный HTML -ответ из View Django.
Установите последнюю версию от PYPI.
pip install django-nextjs Добавьте django_nextjs.apps.DjangoNextJSConfig в INSTALLED_APPS .
Установите URL -адреса Next.js в зависимости от вашей среды.
Если вы обслуживаете свой сайт под ASGI во время разработки, используйте каналы django и добавьте NextJSProxyHttpConsumer , NextJSProxyWebsocketConsumer в asgi.py , как следующий пример.
Примечание. Мы рекомендуем использовать каналы ASGI и Django, потому что это необходимо для быстрого обновления (замена горячего модуля) для правильной работы в 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 Directory |
/_next/... | Proxy to http://localhost:3000 |
/next/... | Служить NEXTJS_PATH/public/next Directory |
Пример конфигурации для 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";
}
Начните с сервером следующего.js:
# Development:
$ npm run dev
# Production:
$ npm run build
$ npm run startНачните с разработки ваших страниц в next.js, затем определите URL Django для каждой страницы Next.js. Вот пример того, как вы можете сделать это:
from django_nextjs . views import nextjs_page
urlpatterns = [
path ( "/nextjs/page" , nextjs_page (), name = "nextjs_page" ),
]Несмотря на то, что это не рекомендуется, иногда вам может потребоваться добавить несколько пользовательских шагов, прежде чем показывать страницу Next.js в Django. Тем не менее, мы советуем перенести эту логику на Next.js, чтобы убедиться, что она применяется даже во время перенаправления на стороне клиента . Если вы окажетесь в этой ситуации, вы можете создать асинхронное представление для каждой страницы, как показано ниже:
from django_nextjs . render import render_nextjs_page
async def jobs ( request ):
# Your custom logic
return await render_nextjs_page ( request )Вы можете изменить HTML -код, который возвращает Next.js в вашем коде Django.
Избегание дублированного кода для Navbar и нижнего колонтитула является общим вариантом использования для этого, если вы используете как следующие шаблоны, так и шаблоны Django. Без этого вам придется написать и сохранить две отдельные версии вашего Navbar и нижнего колонтитула (версия шаблона Django и версия Next.js). Тем не менее, вы можете просто создать шаблон Django для вашего Navbar и вставить его код в начале тега <body> , возвращенного с next.js.
Чтобы включить эту функцию, вам необходимо настроить документ и макет корня в next.js и внести следующие настройки:
id="__django_nextjs_body" как первый атрибут элемента <body> .<div id="__django_nextjs_body_begin" /> в качестве первого элемента внутри <body> .<div id="__django_nextjs_body_end" /> в качестве последнего элемента внутри <body> .Примечание. В настоящее время HTML -настройка не работает с маршрутизатором приложений (Next.js 13+).
Прочитайте этот документ и настройте свой документ.
// 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, который расширяет 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 %} Передайте имя шаблона 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 каталог Next.js, этот файл должен быть в public/next подкаталоге для правильной работы.APPEND_SLASH = False в settings.py вашего проекта Django.py. Кроме того, не добавляйте / в конце следующих путей в urls.pyНастройки по умолчанию:
NEXTJS_SETTINGS = {
"nextjs_server_url" : "http://127.0.0.1:3000" ,
"ensure_csrf_token" : True ,
}nextjs_server_url URL -адрес сервера next.js (запустив npm run dev или npm run start )
ensure_csrf_token Если у пользователя нет токена CSRF, убедитесь, что один из них сгенерирован и включен в начальный запрос на сервер Next.js, позвонив в Django django.middleware.csrf.get_token . Если установлен django.middleware.csrf.CsrfViewMiddleware , первоначальный ответ будет включать заголовок Set-Cookie чтобы сохранить значение токена CSRF на клиенте. Это поведение включено по умолчанию.
ensure_csrf_token ? Возможно, вам потребуется выпустить запросы Post GraphQL для получения данных в next.js getServerSideProps . Если это первый запрос пользователя, не будет CSRF Cookie Cookie, в результате чего запрос сбой, поскольку GraphQL использует POST даже для извлечения данных. Тем не менее, до тех пор, пока функции getServerSideProps не содержат побочных эффектов (то есть они не используют небезопасные методы HTTP или мутации GraphQL), это должно быть хорошо с точки зрения безопасности. Прочитайте больше здесь.
pip install -e '.[dev]'pre-commit install . Грань