IanT8
IanT8

Reputation: 2217

Django Rest Framework Routing for embedded Angular Applications

I'm trying to bundle an Angular app and deploy it as static content in a Django Rest Framework DRF application.

I don't know Django or DRF at all however, I want to take control of the routing to express something like this:

For /admin/* - delegate to built-in Django admin.

For /api/* - delegate to Django Rest Framework

For / only, and /* - treat as static content loaded from "some specified project folder", so / maps to file ./static/index.html /assets/pic.jpg maps to ./static/assets/pic.jpg

I've not been able to achieve the above. All I have is this:

A template view for index.html living at ./templates/index.html - This is the from the Angular project and is not a Django template.

Other webpack bundled content copied manually to ./static such as vendor.|hash|.bundle.js

Another problem is what to do with Assets. In the angular project, HTML views refer to assets via /assets which is at the same level as index.html

I've gotten some control over paths using this command line:

ng build --deploy-url=/static --output-path=../backend/tutorial/static

The deploy-url arg results in bundled assets references in index.html being prefixed by /static which means that Django can serve them (but not favicon.ico for some reason).

The output-path arg dumps all the assets somewhere other than the default "dist" folder.

urlpatterns = [
    url(r'^admin/', include(admin.site.urls)),
    url(r'^api/', include(router.urls)),
    url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')),
    url(r'^', TemplateView.as_view(template_name="index.html")),
]

Url patterns looks like the above.

STATICFILES_DIRS = [
    os.path.join(BASE_DIR, "static")
]

STATIC_URL = '/static/'

These are the static settings. What I need is to be able to say "/static" and "/assets" are both static asset folders.

I'm not sure what TemplateView is (urlPatterns). Maybe there's a StaticFilesView or something that maps a URL to a path on disk?

Upvotes: 0

Views: 514

Answers (1)

Cristobal Barberis
Cristobal Barberis

Reputation: 11

Blockquote These are the static settings. What I need is to be able to say "/static" and "/assets" are both static asset folders. Blockquote

You can achieve that with the following steps:

  1. Add /assets static directory in NGINX site configuration file:

    server {
        ....
        ....
        # your Django project's static files - required
        location /static {
            alias /path/to.../static;
        }
        # your Angular project's static files
        location /assets {
            alias /path/to.../assets;
        }
        ....
        ....
    }
    
  2. In your Django urls.py add:

    from django.views.static import serve as static_serve
    
    urlpatterns = [
        ....
        url(r'^assets/(?P<path>.*)$', static_serve,     
                      {'document_root':'/path/to.../assets'}), 
        ....
        ....
    ]
    

That's it. You don't have to touch the static configuration in Django settings.

    STATIC_URL = '/static/'
    MEDIA_URL = '/media/'
    MEDIA_ROOT = os.path.join(DATA_DIR, 'media')
    STATIC_ROOT = os.path.join(DATA_DIR, 'static')

    STATICFILES_DIRS = (
        os.path.join(BASE_DIR, 'reservation_exchange', 'static'),
    )

Upvotes: 1

Related Questions