28
I have a similar problem.
How can I use vue-router and django rest
framework the same time?
This is my solution to this problem. Hope it helps you.
Expected results:
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
and I try this and it works!
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")),
]
The order is important,
url(r'^.*$', TemplateView.as_view(template_name="index.html")),
is the last one
and this is my vue router
const router = new VueRouter({
mode: 'history',
base: __dirname,
routes: [{
path: '/courses',
component: CourseSet
}, {
path: '/',
component: hello
}]
})
10
Since you have mentioned “single page”:
-
The server is supposed to serve just one page the
index.html
(or whatever else you would like to call it). -
The server and the web application (front-end) code would communicate via api calls, such that the server provides resources and the web-app takes care of using that resource.
-
In case of a missing resource, the server still must not respond with a separate page, it should still respond with a message that the web-app can use.
I have a single page application created in Vue.js that utilizes the HTML5 History Mode for routing
I believe you are using vue-router, which simulates the single-page app to be a full-featured, multi-page application.
You may want to take a look at this and this, but the above holds true for a single page application.
You shared your urlpatterns:
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^api-token-auth/', obtain_jwt_token),
url(r'^.*$', views.home),
]
But other urls like the media or static urls will also point to the same catch all pattern regex. How can I solve this problem?
-
A way you can manage that would be either by, serving on a route other than
'/'
like mentioned above for/app
.urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^api-token-auth/', obtain_jwt_token), url(r'^.*$/app', views.home), ]
and in your router.js file:
new Router({ mode: 'History', base: '/app' routes: [ { path: '/', name: 'name', component: ComponentName } ] })
-
Or prefixing the purpose served by the urls like
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) ]
- [Django]-Dynamic File Path in Django
- [Django]-How can django debug toolbar be set to work for just some users?
- [Django]-Django variable in base.html
7
I’m using VueJS router enabled history mode with Django 2.x by this way:
From app urls.py you need to repath
your frontend url like this:
# 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")),
]
Now history mode working smoothly!
http://sample.com/#/users/login/
Become:
http://sample.com/users/login/
- [Django]-Django.db.utils.OperationalError Could not connect to server
- [Django]-Django url tag multiple parameters
- [Django]-How to select a record and update it, with a single queryset in Django?
3
I solved the issue by using the negative look-ahead regex, so basically anything inside (?!ignore1|ignore2)
will be ignored.
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^api-token-auth/', obtain_jwt_token),
url(r'^(?!admin|api-token-auth|static).*$', views.home),
]
Note: I tried not including admin
and api-token-auth
inside the negative look-ahead and it didn’t work for me, it will still route path that starts with admin
to the views.home
, not sure why as according to my understanding, django should match the earlier ones first.
- [Django]-Django – How to get self.id when saving a new object?
- [Django]-Django rest framework lookup_field through OneToOneField
- [Django]-Understanding Django-LDAP authentication
0
Since index.html is templated (a dynamic page) because it’s served from your views instead of static, this becomes a bit weird.
For production, definitely use nginx or apache to serve the static content in a similar fashion.
For development, this is what I would do:
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))
- [Django]-Django REST Framework: using TokenAuthentication with browsable API
- [Django]-How to use csrf_token in Django RESTful API and React?
- [Django]-Django date to javascript at the template
0
The answer provided above by @billi works fine, up to a point. My problem is that for my SPA I want (need?) to use the Vue <router-view> and <router-link> system. But the router.js maps paths to Vue components, and some of my paths are to Django views via Django urls.py – for example, this will result in a blank page if navigating to /api/places from the Vue router nav, but will resolve correctly to a Django if refreshed.
Ideas?
urls.py
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'),
]
router.js
export default new Router({
mode: 'history',
routes: [
{path: '/search', component: Search},
{path: '/about', component: About},
{path: '/', component: Home},
{path: '/api/places', }
]
})
App.vue
<template>
<div id="app">
<div>
<router-link to="/search">Search</router-link> ::
<router-link to="/about">About</router-link>
<router-link to="/">Home</router-link> ::
<router-link to="/api/places">Place API</router-link> ::
</div>
<router-view></router-view>
</div>
</template>
- [Django]-How to rename items in values() in Django?
- [Django]-How do I get multiple values from checkboxes in Django
- [Django]-Get current user in Model Serializer
0
Don’t know if anyone still looking for the solution.
I build Django Rest API and Vue front totally in a stand alone way. Then when i tried to put the dist folder items in static files of Django and tried to server through gunicorn and NGINX I just could not get the spa working.
Finally did this and very surprisingly it works.
Basically,
forward error page to the index.html of Vue.
Here’s my NGINX config:
location /static/ {
root /root/bdn/bdn/server/;
}
location /media/ {
root /root/bdn/bdn/server/;
}
location ^~ /admin/ { # Define routes to be directed to backend as proxy
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://unix:/run/gunicorn.sock;
}
location ^~ /api/ { # Define routes to be directed to backend as proxy
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://unix:/run/gunicorn.sock;
}
location ^~ /api-auth/ {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://unix:/run/gunicorn.sock;
}
location ^~ /{
root /root/bdn/bdn/server/templates/;
index index.html;
}
error_page 404 /; # THIS IS WHAT IT CAME DOWN TO AFTER HOURS AND HOURS OF SEARCHING
- [Django]-How to add class, id, placeholder attributes to a field in django model forms
- [Django]-Django MySQL error when creating tables
- [Django]-How to keep all my django applications in specific folder