Routing URLs between Django and Angular - django

I'm currently creating a website in Django and Angular. Django is serving the Angular build files. Excluding /api calls, all URLs are returned a template that loads the Angular index. This part works.
The part I'm having trouble with is when I try to lazy-load modules. Angular will try to find a module foo at localhost:8000/foo-module.js, but it's really at localhost:8000/static/mydjangoapp/angular/foo-module.js.
I know I could solve this problem by setting <base href="/" /> in index.html to <base href="/static/mydjangoapp/angular" />, but I want the frontend to be served from /. I could also avoid lazy-loading modules, but I feel like there's a better way to serve Angular from Django using which I can lazy-load.
How can I get Angular to properly fetch the URLs? I'm also having a similar issue with serving Angular assets.

Related

Using Browser Router in react-router-dom with Django backend

I'm building an application that uses React as front-end and Django Rest as back-end.
From front-end, I'm using react-router-dom for declarative routing and Django only serves API
So when user enters an URL like this https://myapp.com/something/something-else, it's actually handle by Django and it will return an error since Django doesn't know which page to lead to with this URL. It should be handled by React instead.
One of the workaround I have is to use a Hash Router, so the URL will look like this (with the hash symbol): https://myapp.com/#/something/something-else
But there have been cases where user will just key the URL without the hash sign (as they didn't know).
Is there away to handle this without using Hash Router?
I can't say exactly because you haven't provided code, or an explanation of your project structure.
How are you doing a hash-router? If you have Django serving a single HTML file, then you should be able to edit your urls.py to pass any URLs that don't match the api to the same page.
As an example, I have a Django website with a Preact frontend, and I have Preact files that are built into static .js files, which are then served by Apache. Django does all URL routing and serves HTML files, which then request the Preact JS files from Apache.

how to make Django play well with Angular URL

In Angular 2 app that's served by Django, how to make the Angular 2 URL work with Django when reloading the page?
Specifically, say a page served by Django has the url http://localhost:8000/home. The page contains 3 tabs and under one of which is an Angular app. Clicking on that tab shows the Angular app, and the url changes to http://localhost:8000/home/ng_app. Now if the browser is refreshed with this url, Django will show a 404, which makes sense because http://localhost:8000/home/ng_app is not present in the Django app.
So how to make the Angular URL work? (entering http://localhost:8000/home/ng_app leads to the Angular app instead of 404). Thanks!
Assuming that your entire app is served from /home, you can just use the following url pattern:
urlpattern('/home/.*$', views.my_angular_homepage)
If you want to also redirect to the route of everything after you can use any of the standard tricks to capture the trailing part of the URL, and then do a $location.path in you angularJS app.
You should consider using hash bangs in your angular app as URLs. Checkout this tutorial I found by googling which also uses has bangs for URLs.
In this way the angular app URLs wont conflict with your Django app and Angular would pick it up for routing purposes
Use url(r'^/home/(?!ng_root/).*$' where ng_root is the root url of the angular static files.
Checkout my blog post for more details https://4sw.in/blog/2016/django-angular2-tutorial/ .

What is the best practice method of using Angular JS routing with a Django backend?

I have created a REST API in Django to pull data from my database. I have a front end application built with Angular that makes calls to that same API. The API has a few URL's, and I have one other URL to serve up index.html and handle the routing. Angular injects the "#/" into the URL. Ideally I would not have that, but when I use the HTML5 mode and location provider, Django picks up the URL and does not see the specified URL in its list and therefore throws an error.
I have seen some resources online, but they are not very clear to me.
Basically, what are accepted best practices with regard to creating angular applications with a Django backend.
I appreciate your help! Thank you in advance.
If you want to serve the index.html for every url and then do the routing in angular you can do somethings like this in your <project_folder>.urls.py
from <your_app> import views
urlpatterns = patterns('',
url(r'^.*$', views.index),
)

Django: How can I serve an angular app without using STATIC_URL during development?

I have a django project which is making use of django-rest-framework to provide an api for an angular client.
The entire angular app is developed separately to the django project, and doesn't make use of any django templates or suchlike.
Eventually the angular app will be served as a static asset via nginx or something along those lines.
However, during development, I would like the django development server to serve the angular app.
The issue I have is that none of the static assets in index.html are prefixed with STATIC_URL or a similar static prefix which django can look for.
Attempting to serve all non-api routes as static files as such:
urlpatterns += static(r'', document_root=settings.ANGULAR_APP_ROOT)
gives an exception
Empty static prefix not permitted
I know that in nodejs express server you can use something like:
app.use(express.static(path.join(config.root, 'app')));
which works seamlessly. I guess it searches for any paths in the configured folder and if any match the requested url, serves them.
I do not want to force django specific code/prefixes into the angular app (ala STATIC_URL etc)
What I'm looking for is some middleware which will offer a fallback route for anything unmatched by the existing urlpatterns and search a filesystem path for a matching asset and serve it if found.
Is it possible to get the static assets served like this with the django development server?

How do you serve vanilla/custom pages in an MVC based site?

Let's say you've setup your site using Pylons, Django and most of the site runs fine and according to the framework used. However, what if you had a custom section that was entirely say, composed of flat html files and its own set of images, which you didn't have time to actually incorporate using the framework and were forced to basically support, under the same domain? Should there be some sort of default controller/view that's super bare minimalistic or do frameworks such as these somehow offer support in some smart way?
I realize also that potentially one could setup a new subdomain and reroute it to an entirely different directory, but I'm just curious as to how one would solve this when forced to deal with a framework.
When serving static pages I'd rather avoid having Django or Pylons handle the request, and handle it with the web server only. Using Nginx, you'd use a directive like:
location / {
root /whatever/the/path/is/;
# if the file exists, return it immediately
if (-f $request_filename) {
break;
}
# pass requests to MVC framework
# i.e. proxy to another server on localhost:
proxy_pass http://127.0.0.1:80;
}
For pylons you should be able to drop your static html files in the public directory. If there isn't a controller for a url then I think pylons looks in the public folder next.
For Django, I would serve these in exactly the same way as you serve your static assets - in your site_media directory, along with subdirs for js, css and img, you could have an html directory. Then the URL would just be /site_media/html/whatever.html.
In Django take a look at flatpages. It's part of the django.contrib package and uses flatpages middleware to serve up flat HTML controlled through the admin interface. For basic purposes, serving up additional about pages or the like this should do the trick.
You could also just create an HTML folder and - using mod_python, at least - set no handler for that path in the Apache configuration file (e.g. vhost.conf).