反应路由和django url冲突
Posted
技术标签:
【中文标题】反应路由和django url冲突【英文标题】:react routing and django url conflict 【发布时间】:2017-04-11 02:41:52 【问题描述】:我使用 reactjs 作为前端,django 作为后端。 React 路由器用于路由。当我刷新由反应路由器路由的页面时,我得到 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: './'
;
urls.py
urlpatterns = [
url(r'^', views.home, name="homePage"),
url(r'^(?:.*)/?$', views.home),
]
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 %
index.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;
【问题讨论】:
我的项目结构和你的一样。我不必在任何地方进行任何额外的 url 配置。你能分享你定义路线的文件吗?还有你定义django url的文件 django 路由还是 reactjs? 您的反应路由器没有路径。上次我使用 React 路由器时,我必须指定路径属性。这是使用 react router 的新方式吗? 它是一个反应路由器 v4 在urls.py
文件中添加url(r'^(?:.*)/?$', base_view),
。
【参考方案1】:
这是受 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 来排除【参考方案2】:这是一个不会导致覆盖其他视图的解决方案,并且不需要您丢弃 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 应该使用或不使用尾部斜杠,区分大小写(如实际路由),并且只会匹配完整的单词(因此像“用户”和“用户”这样的视图不会冲突)。
【讨论】:
【参考方案3】:如果有人遇到同样的问题,在 django 2.0 中,请遵循“Kevin Martin Jose”的回答,但将 url 替换为 re_path
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
放在我的网址中的前端应用程序(反应部分)中。
我的情况也是如此。当然,以防万一,前端的 urls.py
的 url 应该最后包含在您的主应用程序的 urls.py
中,否则我们将吞下 API 请求并为它们返回 app.html 而不是它们的实际响应:D 【参考方案4】:
如果有人想知道,我遇到了确切的问题,Paul S 的回答解决了它。添加答案而不是评论只是因为SO不允许我在cmets中格式化代码sn-ps。我最终在我的urls.py
中混合使用了 django 的新 path()
和旧 urls()
:
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 处理登录、注销和根/
。 React 路由器处理其他所有事情
【讨论】:
"re_path" 是旧“url”的新名称,供看到此内容的人使用。【参考方案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
将是一个视图函数,用于呈现包含您的捆绑应用程序的模板。
【讨论】:
仍然是 404 错误还是您的 React 应用有问题? 我的浏览器挂了。 我不太确定你的意思。当您尝试加载项目时,您的浏览器冻结?除非您在某处有无限循环,否则我不确定是什么原因造成的。您可能需要进行一些开发工具调试。现在至少加载正确的页面了吗? 嗨 Paul S,我偶然发现了这个问题,因为我有同样的问题。不是一个真正的 Django 女孩,所以你能告诉我我应该在 base_view 中放什么吗? 如果您的堆栈中有其他 URL(我使用 django 的内置登录/注销视图),请确保在 URL 堆栈的底部添加通用 URL。以上是关于反应路由和django url冲突的主要内容,如果未能解决你的问题,请参考以下文章