Next.js集成Django项目。
因此,您想在项目中同时使用Django和Next.js。有两种情况:
您正在启动一个新项目,并且想将Django用作后端,而Next.js作为前端。 Django仅服务于API请求。所有前端代码都生活在Next.js中,您不会编写任何Django模板。
在这种情况下,您不需要此软件包(尽管可以使用)。您只需启动Django和Next.js服务器,然后将您的公共网络服务器指向Next.js。
您同时需要django模板和next.js,这些页面应轻松链接。也许您有一个现有的Django项目,该项目的页面由Django模板呈现,并希望在Next.js中进行一些新页面。或者,您想将前端迁移到Next.js,但是由于该项目很大,因此您需要逐步进行。
在这种情况下,此软件包适合您!
从关于Stackoverflow的评论:
在同一服务器上运行2个端口。一个用于django(公共面),另一个用于next.js(内部)。让Django处理所有Web请求。对于每个请求,请查询django视图的Next.js以获取HTML响应。从Django View返回确切的HTML响应。
从PYPI安装最新版本。
pip install django-nextjs添加django_nextjs.apps.DjangoNextJSConfig到INSTALLED_APPS 。
根据您的环境设置Next.js URL。
如果您在开发过程中在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/... | 代理到http://localhost:3000 |
/next/... | 服务NEXTJS_PATH/public/next目录 |
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";
}
启动Next.js服务器:
# Development:
$ npm run dev
# Production:
$ npm run build
$ npm run start首先在Next.js中开发您的页面,然后为每个下一个页面定义一个Django URL。这是一个可以做到这一点的示例:
from django_nextjs . views import nextjs_page
urlpatterns = [
path ( "/nextjs/page" , nextjs_page (), name = "nextjs_page" ),
]即使不建议这样做,有时您可能需要在Django中显示下一个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和页脚的重复代码是常见的用例。没有它,您将不得不编写和维护两个单独的纳维栏和页脚版本(django模板版本和next.js版本)。但是,您只需为您的Navbar创建一个Django模板,然后在<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自定义不使用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模板,该模板扩展了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目录中,则该文件应在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服务器的初始请求中。 If django.middleware.csrf.CsrfViewMiddleware is installed, the initial response will include a Set-Cookie header to persist the CSRF token value on the client.默认情况下启用了此行为。
ensure_csrf_token时?您可能需要在Next.js getServerSideProps中发布GraphQl Post请求以获取数据。如果这是用户的第一个请求,则不会有CSRF cookie,从而导致请求失败,因为GraphQl甚至用于数据获取的帖子。但是,只要getServerSideProps函数是无副作用的(即它们不使用HTTP不安全方法或GraphQL突变),从安全角度来看,这应该很好。在这里阅读更多。
pip install -e '.[dev]'pre-commit install加压钩。 麻省理工学院