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

时间:2015-10-19 18:33:43

标签: javascript python django reactjs react-router

我正在尝试将reactjsreact-router1.x)与我的Django应用程序一起使用,但我很难将所有这些放在一起。这是github项目,因为我在这个问题中没有提供足够的信息。

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

我在path="about"

中创建了routes.js
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错误

enter image description here

我的目标是将前端和后端分开,所以我相信我应该能够将Django用作数据的端点而不是渲染视图。

5 个答案:

答案 0 :(得分:6)

我遇到了同样的问题并最终得到了这个解决方案。

settings.py:

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

urls.py:

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

我不喜欢在django设置中复制所有react-routes,但是如果我们把所有内容放在那里url(r'^.*$'),服务器将始终返回HTTP status_code 200.这只是一种能够返回有效HTTP的方法status_code 404表示不存在的网址。

答案 1 :(得分:1)

我的应用程序为所有有效路由提供相同的客户端JS。请原谅Flask代码。

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

答案 2 :(得分:1)

我受到ramusus' answer的启发。我正在使用(我认为)较新的django.urls.re_path。我对this comment有点怀疑,如果404由前端处理会更好还是更坏。这就是我的实现方式:

frontend / views.py

from django.shortcuts import render

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

frontend / urls.py

from django.urls import re_path

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

main / 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...

答案 3 :(得分:0)

基于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'))
    ]

答案 4 :(得分:0)

我可以通过在React应用程序中使用HashRouter来解决此问题。这会在网址的开头添加一个#,您可以在Django urls.py中使用一个空路径(您的路径看起来像这样:example.com/#/about/

Here is a good explanation(别忘了投票)。

您的文件如下所示:

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'))
]