react路由和 django url 冲突

IT技术 javascript python django reactjs react-router
2021-03-25 08:44:12

我使用 reactjs 作为前端,使用 django 作为后端。React 路由器用于路由。当我刷新由react-router路由的页面时,我得到 django 404 Page Not Found error如果我刷新主页,我不会收到任何此类错误,因为主页也是由 django 模板使用其 url 呈现的。

我必须在 webpack 中配置它吗?我的项目结构是我将 django 和 reactjs 分开。我创建了一个文件夹作为 reactjs 文件所在的前端。

更新

主页模板包含诸如 addrestaurant 之类的路线的所有链接。

我的 webpack.config 文件

const path = require("path");
if(!process.env.NODE_ENV) {
    process.env.NODE_ENV = 'development';
}

module.exports = {
  entry: [
    './src/index.js'
  ],
  output: {
    path: path.join("../app/static/build/", "js"),
    filename: "app.js",
    publicPath: "../app/static/build/"
  },
  devtoo: 'source-map',
  debug: true,
  module: {
    loaders: [{
      exclude: /node_modules/,
      loader: 'babel',
      query: {
        presets: ['react', 'es2015', 'stage-1']
      }
    },
    {test: /\.(jpe?g|png|gif|svg)$/i, loader: "url-loader?name=images/[name].[ext]"},
    ]
  },
  resolve: {
    extensions: ['', '.js', '.jsx']
  },
  devServer: {
    historyApiFallback: true,
    contentBase: './'
  }
};

网址.py

urlpatterns = [
    url(r'^', views.home, name="homePage"),
    url(r'^(?:.*)/?$', views.home),
]

主页.html

{% extends 'base.html' %}

{% block title %} Foodie | Homepage {% endblock title%}

{% block content %}
  <div class="homepage">
  </div>
{% endblock %}

{% block js %}
  {{ block.super }}
  <script type="text/javascript">
  var data = {
         isUserAuthenticated:{% if request.user.is_authenticated %}true{% else %}false{% endif %}
    };
    console.log('data',data);
    $(function() {
      app.showHomePage(".homepage",data);
    });
  </script>
{% endblock %}

索引.js

window.app = {
      showHomePage: function(id,data){
          render(
            <Provider store={createStoreWithMiddleware(reducers)}>
                <Router>
                 <App />
                </Router>
            </Provider>, document.querySelector(id)
          );
      },
}

Banner 是 App 组件的子组件

const Banner = (props) => (
   <div className="navbar-container">
        <div className="ui container">
            <div className="ui large secondary menu">
                <a className="toc item">
                    <i className="sidebar icon"></i>
                </a>
                <div className="item logo">
                    <div className="ui logo shape">
                        <div className="sides">
                            <div className="active ui side">
                                Foodie
                            </div>
                        </div>
                    </div>
                </div>
                <Link to="/restaurant" className="active item tab">Home</Link>
                <Link to='/addrestaurant' className='item tab'>Add Restaurant</Link>
                <Link to="/products" className="item tab">Products</Link>
                <div className="right item">
                    <a href="" id="bookingInfoButton" className="ui white inverted button">Booking</a>
                </div>
            </div>
        </div>
      </div>
);

export default Banner;
5个回答

问题可能是您尚未配置 URL 来处理 React Router 中定义的路由。在您的 Django 中,urls.py您应该使用 catch all 将所有 URL 匹配到您的索引模板

urlpatterns += [
    # match the root
    url(r'^$', base_view),
    # match all other pages
    url(r'^(?:.*)/?$', base_view),
]

base_view将是一个视图函数,它呈现一个包含捆绑应用程序的模板。

嗨,Paul S,我偶然发现了这个问题,因为我有同样的问题。不是真正的 Django 女孩,所以你能告诉我应该在 base_view 中放什么吗?
2021-05-31 08:44:12
我不太确定你的意思。当您尝试加载项目时,您的浏览器卡住了?我不确定是什么导致了这种情况,除非你在某处有一个无限循环。您可能需要进行一些开发工具调试。现在至少加载了正确的页面吗?
2021-06-03 08:44:12
我的浏览器挂了。
2021-06-07 08:44:12
它仍然是 404 错误还是您的 React 应用程序有问题?
2021-06-12 08:44:12
如果您的堆栈中有其他 URL(我使用 django 的内置登录/注销视图),请确保在您的 URL 堆栈底部添加全能 URL。
2021-06-20 08:44:12

如果有人遇到同样的问题,在 django 2.0 中,按照“Kevin Martin Jose”的回答,而是re_path替换url

from django.urls import path, re_path

urlpatterns = [
    path('login/', LoginView.as_view(), name='login'),
    path('logout/', LogoutView.as_view()),
    path('/', login_required(TemplateView.as_view(template_name="app.html"), 
    login_url='login')),
    re_path(r'^(?:.*)/?$', login_required(TemplateView.as_view(template_name="app.html"), 
    login_url='login')),
]
谢谢!这真的奏效了。我有 2 个单独的 django 应用程序,一个用于 django-rest,另一个用于反应。我只需要re_path在我的网址中放置前端应用程序(反应部分)中的 。
2021-05-28 08:44:12
我的情况也是如此。当然,为了以防万一,前端的urls.pyurl 应该包含在主应用程序的最后,urls.py否则我们将吞下 API 请求并为它们返回 app.html 而不是它们的实际响应:D
2021-06-15 08:44:12

如果有人想知道,我遇到了确切的问题,而 Paul S 的回答解决了它。添加答案而不是评论只是因为 SO 不允许我在评论中格式化代码片段。我结束了使用Django的新的混合物path()和老urls()在我的urls.py

urlpatterns = [
    path('login/', LoginView.as_view(), name='login'),
    path('logout/', LogoutView.as_view()),
    path('/', login_required(TemplateView.as_view(template_name="app.html"), 
    login_url='login')),
    url(r'^(?:.*)/?$',    login_required(TemplateView.as_view(template_name="app.html"), 
    login_url='login')),
]

Django 处理登录、注销和 root /React 路由器处理其他一切

“re_path”是那些看到这个的人的旧“url”的新名称。
2021-06-04 08:44:12

这是受 Kevin Jones 和 Paul S 答案启发的答案。我在使用正则表达式和托管 REST API 时遇到问题。如果我的前端应用程序在进行 API 调用时没有附加斜线,它就不会匹配并且会被路由回前端。这是因为 django 设置APPEND_SLASH=True要求它urlpatterns在附加斜杠并再次尝试之前通过并失败一次。因此,这里有一个正则表达式,它只排除以“api”或“admin”开头的任何内容,否则将其发送到前端。

urlpatterns = [
path("admin/", admin.site.urls),
path("api/", include(router.urls)),  # from rest_framework
re_path('(^(?!(api|admin)).*$)',
    TemplateView.as_view(template_name="build/index.html")),
] 
感谢检查 api/admin .. 也可以添加 meda/static url 来排除
2021-06-03 08:44:12

这是一个不会导致其他视图覆盖的解决方案,并且不需要您丢弃 404 处理程序。

缺点是这需要保持最新的路线列表,但这就是该文件的用途。

urls.py

from django.urls import re_path
from myapp import views

# This wrapper turns your list into a regex URL matcher
react_views_regex = r'\/|\b'.join([

    # List all your react routes here
    'view1',
    'view2'

]) + r'\/'

urlpatterns = [
    # Change views.index to whatever your view is
    re_path(react_views_regex, views.index),
]

这些 URL 应该使用或不使用斜杠,区分大小写(如真实路由),并且只会匹配完整的单词(因此像“user”和“users”这样的视图不会冲突)。