Integrasi selanjutnya.js untuk proyek Django.
Jadi, Anda ingin menggunakan Django dan Next.js dalam proyek Anda. Ada dua skenario:
Anda memulai proyek baru dan Anda ingin menggunakan Django sebagai back-end dan Next.js sebagai front-end. Django hanya melayani permintaan API. Semua kode front-end tinggal di Next.js dan Anda tidak menulis template django.
Dalam skenario ini Anda tidak memerlukan paket ini (meskipun Anda dapat menggunakannya). Anda cukup memulai server Django dan Next.js dan arahkan server web publik Anda ke Next.js.
Anda memerlukan kedua templat Django dan Next.js pada saat yang sama dan halaman -halaman itu harus dengan mudah saling terhubung. Mungkin Anda memiliki proyek Django yang ada yang memiliki halaman yang diberikan oleh template Django dan menginginkan beberapa halaman baru di Next.js. Atau Anda ingin memigrasi front-end Anda ke Next.js tetapi karena proyeknya besar, Anda perlu melakukannya secara bertahap.
Dalam skenario ini, paket ini cocok untuk Anda!
Dari komentar di StackOverflow:
Jalankan 2 port di server yang sama. Satu untuk Django (menghadap publik) dan satu untuk Next.js (internal). Biarkan Django menangani semua permintaan web. Untuk setiap permintaan, query Next.js dari Django View untuk mendapatkan respons HTML. Kembalikan respons HTML yang tepat dari tampilan Django.
Instal versi terbaru dari PYPI.
pip install django-nextjs Tambahkan django_nextjs.apps.DjangoNextJSConfig ke INSTALLED_APPS .
Siapkan URL Next.js tergantung pada lingkungan Anda.
Jika Anda melayani situs Anda di bawah ASGI selama pengembangan, gunakan saluran Django dan tambahkan NextJSProxyHttpConsumer , NextJSProxyWebsocketConsumer ke asgi.py seperti contoh berikut.
Catatan: Kami sarankan menggunakan saluran ASGI dan Django, karena diperlukan untuk refresh cepat (penggantian modul panas) untuk bekerja dengan baik di 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 )),
# ...
}
) Jika tidak (jika melayani di bawah WSGI selama pengembangan), tambahkan yang berikut ini ke awal urls.py :
path ( "" , include ( "django_nextjs.urls" )) PERINGATAN: Jika Anda melayani di bawah ASGI, jangan menambahkan ini ke urls.py Anda. Itu dapat menyebabkan kebuntuan.
Dalam produksi, gunakan proxy terbalik seperti nginx atau caddy:
| Url | Tindakan |
|---|---|
/_next/static/... | Sajikan Direktori NEXTJS_PATH/.next/static |
/_next/... | Proxy to http://localhost:3000 |
/next/... | Sajikan Direktori NEXTJS_PATH/public/next |
Contoh konfigurasi untuk 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";
}
Mulai server Next.js:
# Development:
$ npm run dev
# Production:
$ npm run build
$ npm run startMulailah dengan mengembangkan halaman Anda di Next.js, lalu tentukan URL Django untuk setiap halaman berikutnya.js. Berikut adalah contoh bagaimana Anda bisa melakukan ini:
from django_nextjs . views import nextjs_page
urlpatterns = [
path ( "/nextjs/page" , nextjs_page (), name = "nextjs_page" ),
]Meskipun tidak disarankan, kadang -kadang Anda mungkin perlu menambahkan beberapa langkah khusus sebelum menampilkan halaman Next.js di Django. Namun, kami menyarankan memindahkan logika ini ke Next.js untuk memastikan itu diterapkan bahkan selama pengalihan sisi klien . Jika Anda menemukan diri Anda dalam situasi ini, Anda dapat membuat tampilan asinkron untuk setiap halaman seperti yang ditunjukkan di bawah ini:
from django_nextjs . render import render_nextjs_page
async def jobs ( request ):
# Your custom logic
return await render_nextjs_page ( request )Anda dapat memodifikasi kode HTML yang dikembalikan oleh Next.js dalam kode Django Anda.
Menghindari kode duplikat untuk navbar dan footer adalah kasus penggunaan umum untuk ini jika Anda menggunakan template next.js dan django. Tanpa itu, Anda harus menulis dan memelihara dua versi terpisah dari navbar dan footer Anda (versi template django dan versi next.js). Namun, Anda dapat membuat template django untuk navbar Anda dan memasukkan kodenya di awal tag <body> yang dikembalikan dari next.js.
Untuk mengaktifkan fitur ini, Anda perlu menyesuaikan dokumen dan tata letak root di Next.js dan membuat penyesuaian berikut:
id="__django_nextjs_body" sebagai atribut pertama dari elemen <body> .<div id="__django_nextjs_body_begin" /> sebagai elemen pertama di dalam <body> .<div id="__django_nextjs_body_end" /> Sebagai elemen terakhir di dalam <body> .Catatan: Saat ini kustomisasi HTML tidak berfungsi dengan router aplikasi (Next.js 13+).
Baca dokumen ini dan sesuaikan dokumen Next.js Anda:
// 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 >
. . . Tulis template django yang memperluas 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 %} Lewati nama template ke nextjs_page atau 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, file itu harus di subdirektori public/next untuk bekerja dengan benar.APPEND_SLASH = False di settings.py proyek Django Anda. Juga, jangan menambah / di akhir jalur NextJS di urls.pyPengaturan default:
NEXTJS_SETTINGS = {
"nextjs_server_url" : "http://127.0.0.1:3000" ,
"ensure_csrf_token" : True ,
}nextjs_server_url URL dari server Next.js (dimulai oleh npm run dev atau npm run start )
ensure_csrf_token Jika pengguna tidak memiliki token CSRF, pastikan bahwa seseorang dihasilkan dan dimasukkan dalam permintaan awal ke server berikutnya.js dengan memanggil django.middleware.csrf.get_token dari Django. Jika django.middleware.csrf.CsrfViewMiddleware diinstal, respons awal akan menyertakan header Set-Cookie untuk bertahan dari nilai token CSRF pada klien. Perilaku ini diaktifkan secara default.
ensure_csrf_token ? Anda mungkin perlu menerbitkan permintaan Posting GraphQL untuk mengambil data di Next.js getServerSideProps . Jika ini adalah permintaan pertama pengguna, tidak akan ada cookie CSRF, menyebabkan permintaan gagal karena GraphQL menggunakan Post bahkan untuk pengambilan data. Namun, selama fungsi getServerSideProps bebas efek samping (yaitu, mereka tidak menggunakan metode http yang tidak aman atau mutasi graphql), ini seharusnya baik-baik saja dari perspektif keamanan. Baca lebih lanjut di sini.
pip install -e '.[dev]'pre-commit install . Mit