ルーティングにHTML5履歴モードを利用するVue.jsで作成された単一ページアプリケーションがあり、htmlファイルはDjangoで提供されます。
rls.py Djangoは次のようになります:
urlpatterns = [
url(r'^$', views.home),
url(r'^admin/', admin.site.urls),
url(r'^api-token-auth/', obtain_jwt_token),
]
そしてviews.home:
def home(request):
return render(request, 'index.html')
次のシナリオを検討してください。
/
)ホームページは単一ページのVuejsアプリに必要なindex.htmlで応答するため、想定どおりに動作します。
/username/12
)に移動します。Vue router。
rls.pyパターンには/username/12
がないため、Page not found(404)と表示されます。
今、私はrls.pyに別のパターンを提供して、次のように最後の順序ですべてのパターンをキャッチできます:
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^api-token-auth/', obtain_jwt_token),
url(r'^.*$', views.home),
]
ただし、メディアや静的URLなどの他のURLも同じcatch all pattern regexを指します。この問題を解決するにはどうすればよいですか?
同様の問題があります。
どのようにしてvue-routerとDjango RESTフレームワークを同時に使用できますか??
これがこの問題に対する私の解決策です。お役に立てば幸いです。
予期された結果:
_http://127.0.0.1:8000/ <-- TeamplateView index.html using vue
http://127.0.0.1:8000/course <-- vue-router
http://127.0.0.1:8000/api <-- rest framework
http://127.0.0.1:8000/admin <-- Django admin
_
これを試してみるとうまくいきます!
urls.py
_urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')),
url(r'^api/', include(router.urls)),
url(r'^.*$', TemplateView.as_view(template_name="index.html")),
]
_
順序は重要です。
url(r'^.*$', TemplateView.as_view(template_name="index.html")),
が最後です
これは私のvue router
_const router = new VueRouter({
mode: 'history',
base: __dirname,
routes: [{
path: '/courses',
component: CourseSet
}, {
path: '/',
component: hello
}]
})
_
「単一ページ」について言及したので、
サーバーは、index.html
(またはそれ以外の任意のページ)を1ページだけ提供することになっています。
サーバーとWebアプリケーション(フロントエンド)コードは、API呼び出しを介して通信し、サーバーがリソースを提供し、Webアプリがそのリソースを使用するようにします。
リソースが欠落している場合でも、サーバーは別のページで応答してはならず、Webアプリが使用できるメッセージで応答する必要があります。
ルーティングにHTML5履歴モードを利用するVue.jsで作成された単一ページアプリケーションがあります。
vue-router を使用していると思います。これは、シングルページアプリをフル機能のマルチページアプリケーションとしてシミュレートします。
this と this を確認することをお勧めしますが、上記は単一ページのアプリケーションにも当てはまります。
Urlpatternsを共有しました:
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^api-token-auth/', obtain_jwt_token),
url(r'^.*$', views.home),
]
ただし、メディアや静的URLなどの他のURLも、同じキャッチオールパターン正規表現を指します。この問題を解決するにはどうすればよいですか?
これを管理する方法は、'/'
について上記で説明したように、/app
以外のルートでサービスを提供することです。
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^api-token-auth/', obtain_jwt_token),
url(r'^.*$/app', views.home),
]
そしてあなたのrouter.jsファイルで:
new Router({
mode: 'History',
base: '/app'
routes: [
{
path: '/',
name: 'name',
component: ComponentName
}
]
})
または、次のようなURLが提供する目的の前に
urlpatterns = [
url(r'^api/admin/', admin.site.urls),
url(r'^api/api-token-auth/', obtain_jwt_token),
url(r'^.*$', views.home),
url(r'^.*$/assets', your-static-assets)
]
Index.htmlは静的ではなくビューから提供されるため、テンプレート(動的ページ)であるため、これは少し奇妙なものになります。
本番環境では、必ずnginxまたはApacheを使用して、同様の方法で静的コンテンツを提供してください。
開発のために、これは私がすることです:
from Django.contrib.staticfiles.views import serve
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^api-token-auth/', obtain_jwt_token),
]
# Serve your static media (regex matches *.*)
if settings.DEBUG:
urlpatterns.append(url(r'(?P<path>.*\..*)$', serve))
# Serve your single page app in every other case
urlpatterns.append(url(r'^.*$', views.home))
私は否定的な先読み正規表現を使用して問題を解決したので、基本的に(?!ignore1|ignore2)
内のすべては無視されます。
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^api-token-auth/', obtain_jwt_token),
url(r'^(?!admin|api-token-auth|static).*$', views.home),
]
注:否定的な先読み内にadmin
とapi-token-auth
を含めないようにしましたが、うまくいきませんでした。admin
で始まるパスをviews.home
にルーティングしますが、理由はわかりません私の理解によると、Djangoは最初のものと最初に一致するはずです。
上記の@billiによる回答は、ある程度まではうまく機能します。私の問題は、SPAにVue <router-view>と<router-link>システム。しかし、router.jsはパスをVueコンポーネントにマッピングし、私のパスの一部はDjango urls.pyを介してDjangoビューに移動します。たとえば、これにより、ナビゲーションVueルーターナビゲーションから/ api/placesに変更しますが、更新するとDjangoに正しく解決されます。
アイデア?
rls.py
urlpatterns = [
# Django
path('admin', admin.site.urls),
url(r'^api-auth/', include('rest_framework.urls')),
url(r'^api/places$', views.PlaceList.as_view()),
# catchall to Vue single page app
url(r'^.*$', TemplateView.as_view(template_name='myapp/spa.html'), name='home'),
]
router.js
export default new Router({
mode: 'history',
routes: [
{path: '/search', component: Search},
{path: '/about', component: About},
{path: '/', component: Home},
{path: '/api/places', }
]
})
App.vue
<template>
<div id="app">
<div>
<router-link to="/search">Search</router-link> ::
<router-link to="/about">About</router-link>
<router-link to="/">Home</router-link> ::
<router-link to="/api/places">Place API</router-link> ::
</div>
<router-view></router-view>
</div>
</template>