簡體   English   中英

使用 Django + react-router 找不到 404 頁面

[英]404 page not found using Django + react-router

我正在嘗試在我的 Django 應用程序中使用reactjsreact-router ( 1.x ),但我很難將所有這些放在一起。 這是 github 項目,以防萬一我沒有在這個問題中提供足夠的信息。

https://github.com/liondancer/django-cherngloong

我在我的routes.js創建了一個path="about"

var routes = (
    <Router>
        <Route path="/" component={ Views.Layout }>
            <IndexRoute component={ Views.Index } />
            <Route path="about" component={ Views.About } />
        </Route>
        <Route path="*" component={ Views.RouteNotFound } />
    </Router>
);

export default routes;

我的layout.js

class Layout extends React.Component {
    constructor(props) {
        super(props);
    }
    render() {
        return (
            <div id="review-web">
                <header className="header">
                    <LogoElement />
                    <CenterPiece />
                </header>
                <div>
                    { React.cloneElement(this.props.children, { path: this.props.path }) }
                </div>
                <Footer />
            </div>
        );
    }
}

export default Layout;

當我輸入localhost.8000/about出現404 Django 錯誤

在此處輸入圖片說明

我的目標是保持前端和后端分開,所以我相信我應該能夠將 Django 用作數據的端點而不是渲染視圖。

我遇到了同樣的問題,最終得到了這個解決方案。

設置.py:

REACT_ROUTES = [
    'login',
    'signup',
    'password-reset',
    'password-change',
    'about',
    ...
]

網址.py:

routes = getattr(settings, 'REACT_ROUTES', [])
urlpatterns = [
    ...
    url(r'^(%s)?$' % '|'.join(routes), TemplateView.as_view(template_name='index.html')),
]

我不喜歡在 django 設置中復制所有的反應路由,但是如果我們把所有的東西都放在那里url(r'^.*$') ,服務器將總是返回 HTTP status_code 200。這只是一種能夠返回的方法不存在的 url 的有效 HTTP status_code 404。

我的應用程序為所有有效路由提供相同的客戶端 JS。 請原諒 Flask 代碼。

@blueprint.route('/stuff/<path:path>', methods=["get"])
@blueprint.route('/', methods=["get"])
def index(path=None):
    return render_template('app.html')

我受到了ramusus 的回答的啟發。 我正在使用(我認為)較新的django.urls.re_path 我對這個評論有點懷疑,如果 404 由前端處理會更好或更糟。 我是這樣實現的:

前端/views.py

from django.shortcuts import render

def index(request):
    return render(request, 'frontend/index.html')

前端/urls.py

from django.urls import re_path

# Catch all pattern
urlpatterns = [
    re_path('.*/', views.index, name='index'),
]

主/ urls.py

from django.contrib import admin
from django.urls import path, include
from rest_framework.authtoken import views


urlpatterns = [
    path('admin/', admin.site.urls),
    ...,
    path('api-auth/', include('rest_framework.urls')),
    path('', include('some_apps.urls')),
    ...,
    # Put this at the end! This way, Django tries all 
    # its API URLs and if it doesn't find anything it
    # redirects to the frontend
    path('', include('frontend.urls'))
]

反應前端

// stuff ...

const Page404 = () => {
  return (
    <h3>404 - Not found</h3>
  );
};

class App extends Component {
    render(){
        return (
            <Router>
                <Navbar />

                <Switch>
                    // React handles any paths you specify, e.g. within the switch
                    <Route exact path='/some_paths/' component={SomeComponents} />
                    // If nothing matches...
                    <Route component={Page404} />
                </Switch>
            </Router>
        )
    }
}

// stuff...

根據 ramusus 的回答,這就是我現在修復它的方式。

由於 url 不再適用於 Django 2 及更高版本。 並且 ramuses 的答案似乎也在使用 Python 2,查看字符串格式。 這是使用 Python 3(.6)。

(雖然我確信有一種更優雅的方法可以做到這一點,但它有效並幫助我在啟動和運行項目方面更進一步。)

settings.py:(如 ramusus 建議)

REACT_ROUTES = [
    'login',
    'signup',
    'password-reset',
    'password-change',
    'about',
    ...
]

在主 urls.py 中:(部分如 ramusus 建議的那樣)

from django.conf import settings

react_routes = getattr(settings, 'REACT_ROUTES', [])

for route in react_routes:
    urlpatterns += [
        path('{}'.format(route), TemplateView.as_view(template_name='index.html'))
    ]

我可以通過在 React 應用程序中使用HashRouter來解決這個問題。 這會在 url 的開頭添加一個# ,您可以在 Django urls.py使用空路徑(您的路徑如下所示: example.com/#/about/

這是一個很好的解釋(不要忘記投票)。

您的文件將如下所示:

App.tsx

<Router>
    <Switch>
        <Route path="/article/:articleID">
            <Article />
        </Route>
        {/* your routes */}
    </Switch>
</Router>

然后只是一個空的路徑。 urls.py

urlpatterns = [
    path("", TemplateView.as_view(template_name='index.html'))
]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM