2017-03-17 68 views
9

我在Vue.js中创建了一个使用HTML5历史模式进行路由的单页应用程序,并且该html文件与Django一起提供。处理单页面应用程序url和django url

urls.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') 

考虑以下情形:

  1. 用户访问主页(即/

因为主页响应单页Vuejs应用程序所需的index.html,它的工作原理与它应该的一样。

  1. 从那里用户导航到关于页面(即,/username/12)。

它仍然正常工作,因为它的Vue路由器导航。

  1. 现在,用户刷新页面。

因为有一个在urls.py模式没有/username/12,它会显示找不到网页(404)

现在,我可以提供urls.py另一种模式赶在最后订单的所有模式,因为这:

urlpatterns = [ 
    url(r'^admin/', admin.site.urls), 
    url(r'^api-token-auth/', obtain_jwt_token), 
    url(r'^.*$', views.home), 
] 

但其他网址,如媒体或静态网址也将指向同捕捉所有图案正则表达式。我怎么解决这个问题?

+1

包罗万象的网址是要走的路。这不会影响媒体或静态,因为它们不是由Django在制作中提供的。 –

回答

2

既然你提到的“单页”:

  1. 服务器应该服务只有一个页面的index.html(或者其他任何你想称呼它)。

  2. 服务器和Web应用程序(前端)代码将通过api调用进行通信,以便服务器提供资源并且web-app负责使用该资源。

  3. 如果资源缺失,服务器仍然不能使用单独的页面进行响应,它仍应回应一条消息,指出该Web应用程序可以使用该消息。

我在Vue公司创造了一个单页的应用程序。JS利用HTML5的历史模式路由

我相信你正在使用vue-router,它模拟了单页的应用程序是一个全功能,多页应用。


你可能想看看thisthis,但是对于单页的应用程序上面也是如此。


您共享您的URL模式:

urlpatterns = [ 
    url(r'^admin/', admin.site.urls), 
    url(r'^api-token-auth/', obtain_jwt_token), 
    url(r'^.*$', views.home), 
] 

但其他网址,如媒体或静态网址也将指向同一个包罗万象的模式正则表达式。我怎么解决这个问题?

  1. 的一种方式,您可以管理,这将是或者通过,服务比'/'其他路线上像上面提到的/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 
        } 
        ] 
    }) 
    
  2. 或者通过加前缀的网址服务的宗旨一样

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

我有类似的问题。

如何使用vue-router和django休息 框架同时

这是我解决这个问题的方法。希望它可以帮助你。

希望得到的结果:

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路由器

const router = new VueRouter({ 
    mode: 'history', 
    base: __dirname, 
    routes: [{ 
     path: '/courses', 
     component: CourseSet 
    }, { 
     path: '/', 
     component: hello 
    }] 
}) 

My project on GitHub

0

由于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)) 
相关问题