处理单页面应用程序url和django url

时间:2017-03-17 18:20:53

标签: django vue.js single-page-application vuejs2

我在Vue.js中创建了一个单页面应用程序,它利用HTML5历史记录模式进行路由,而html文件是用Django提供的。

django的 urls.py 是这样的:

$('.form-group').on('change',':input',function(){
  var $this = $(this);
  var $group = $this.closest('.form-group'); 



  $group.attr('is-filled',!!($group.find('input').filter(':checked').length) );

  var $text_inputs = $group.find('.text');

  if(!$text_inputs.length){
    return void(0);
  }

  var count = 0;

  $.each($text_inputs,function(){
    var $that = $(this);
    if($that.val() && $.trim($that.val()).length ){
      count++;
    }

  });  

  $group.attr('is-filled',!!(count) );  
});

$('.form-group').on('change',':input',updateCount);




function updateCount(){
  $('#count').html('Current Count = ' + $('.form-group[is-filled="true"]').length);

}

views.home

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

考虑以下情况:

  1. 用户访问主页(即def home(request): return render(request, 'index.html')
  2. 因为主页以单页Vuejs应用程序的必需index.html响应,所以它的工作方式与它应该的一样。

    1. 从那里用户导航到about页面(即/)。
    2. 它仍在正常工作,因为它使用Vue路由器进行导航。

      1. 现在,用户刷新页面。
      2. 由于 urls.py 模式中没有/username/12,因此会显示找不到网页(404)

        现在,我可以在 urls.py 中提供另一种模式来捕获最后一个顺序中的所有模式:

        /username/12

        但是其他网址如媒体或静态网址也会指向相同的捕获所有模式正则表达式。我该如何解决这个问题?

6 个答案:

答案 0 :(得分:16)

  

我有类似的问题。

     

如何使用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

答案 1 :(得分:4)

由于您已经提到了&#34;单页&#34;:

  1. 服务器应该只为index.html(或其他您想要调用的其他内容)提供一页。

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

  3. 如果资源缺失,服务器仍然不能使用单独的页面进行响应,它仍应响应网络应用程序可以使用的消息。

  4.   

    我在Vue.js中创建了一个单页应用程序,它利用HTML5历史记录模式进行路由

    我相信您正在使用vue-router,它会将单页应用程序模拟为功能齐全的多页应用程序。

    您可能需要查看thisthis,但上述内容适用于单页应用。

    您分享了您的网址:

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

答案 2 :(得分: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))

答案 3 :(得分:0)

@billi上面提供的答案在一定程度上效果很好。我的问题是,对于我的SPA,我希望(需要?)使用Vue << em> router-view >和<< em> router-link >系统。但是router.js会将路径映射到Vue组件,而我的一些路径是通过Django urls.py到Django视图的-例如,如果从Vue路由器导航导航到/ api / places,这将导致空白页,但是如果刷新,将正确解析为Django。

想法?

urls.py

SKU

router.js

urlpatterns = [
    # Django
    path('admin', admin.site.urls),
    url(r'^api-auth/', include('rest_framework.urls')),
    url(r'^api/places$', views.PlaceList.as_view()),

    # catchall to Vue single page app
    url(r'^.*$', TemplateView.as_view(template_name='myapp/spa.html'), name='home'),
]

App.vue

export default new Router({
  mode: 'history',
  routes: [
    {path: '/search', component: Search},
    {path: '/about', component: About},
    {path: '/', component: Home},
    {path: '/api/places', }
  ]
})

答案 4 :(得分:0)

我通过使用否定的超前正则表达式解决了这个问题,因此(?!ignore1|ignore2)中的所有内容都将被忽略。

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

注意:我尝试不将adminapi-token-auth包括在否定的预先查找之内,但它对我不起作用,它仍会将以admin开头的路径路由到views.home,不确定为什么按照我的理解,Django应该首先匹配早期版本。

答案 5 :(得分:0)

通过这种方式,我正在Django 2.x中使用启用了VueJS路由器的历史记录模式:

您需要从应用urls.py repath像这样# urls.py from django.urls import path, include from django.urls import re_path urlpatterns = [ path('', TemplateView.as_view(template_name="application.html"), name="app", ), # ... rest of your urls ] urlpatterns += [ re_path('^.*$', TemplateView.as_view(template_name="application.html")), ]

http://sample.com/#/users/login/

现在的历史记录模式运行顺畅!

http://sample.com/users/login/

成为:

$(document).ready(function(){
  $("#my-unique-id").cropzee({startSize: [40, 40, '%'],});
});