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 يتعامل مع جميع طلبات الويب. لكل طلب ، Query Next.js من عرض Django للحصول على استجابة HTML. إرجاع استجابة HTML الدقيقة من عرض 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/... | وكيل إلى 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";
}
START NEXT.JS Server:
# 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 و Footer حالة استخدام شائعة لهذا إذا كنت تستخدم قوالب Next.js و Django. بدون ذلك ، يجب عليك كتابة وصيانة نسختين منفصلتين من Navbar و Fooler (إصدار قالب 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 حاليًا مع 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 لـ Next.js ، فيجب أن يكون هذا الملف في الدليل public/next للعمل بشكل صحيح.APPEND_SLASH = False في settings.py مشروع Django الخاص بك. أيضا ، لا تضيف / في نهاية مسارات NextJS في urls.pyالإعدادات الافتراضية:
NEXTJS_SETTINGS = {
"nextjs_server_url" : "http://127.0.0.1:3000" ,
"ensure_csrf_token" : True ,
}nextjs_server_url عنوان URL لـ NEXT.JS Server (الذي بدأه npm run dev أو npm run start )
ensure_csrf_token إذا لم يكن لدى المستخدم رمز CSRF ، فتأكد من إنشاء واحد وإدراجه في الطلب الأولي إلى خادم Next.js عن طريق الاتصال بـ django.middleware.csrf.get_token 's Django. إذا تم تثبيت django.middleware.csrf.CsrfViewMiddleware ، ستتضمن الاستجابة الأولية رأسًا Set-Cookie لاستمرار قيمة الرمز المميز CSRF على العميل. يتم تمكين هذا السلوك بشكل افتراضي.
ensure_csrf_token ؟ قد تحتاج إلى إصدار طلبات نشر GraphQL لجلب البيانات في next.js getServerSideProps . إذا كان هذا هو الطلب الأول للمستخدم ، فلن يكون هناك ملف تعريف ارتباط CSRF ، مما يتسبب في فشل الطلب نظرًا لأن GraphQL يستخدم المنشور حتى لجلب البيانات. ومع ذلك ، طالما أن وظائف getServerSideProps خالية من التأثير الجانبي (أي أنها لا تستخدم أساليب HTTP غير الآمنة أو طفرات GraphQL) ، يجب أن يكون هذا جيدًا من منظور أمان. اقرأ المزيد هنا.
pip install -e '.[dev]'pre-commit install . معهد ماساتشوستس للتكنولوجيا