Quit thinking in terms of MVC. MVC alone only describes the interactions well if everything happens on the server-side. You need to think at a higher level of abstraction. For example, Data Layer (ex database), API layer (ex server-side), Client Layer (Webapp, IOS app, Android App).
A basic SPA works on the premise that the whole site runs on one big HTML file. Reloads don't require a round-trip to the server because you're basically showing/hiding different sections of code.
In practice that's not necessarily true because the framework (ex Angular) can pull template partials and data from URLs in the background. It sounds like you understand this much but can't figure out how concerns should be separated between server/client.
For templating, do it the same as you would in Django. Except, instead of loading the files from a local directory you fetch the partials from the server.
For generating views that include data you'll need to make a controller that can fetch the data and use it in the view partial. There are many ways to go about this but the most common is to simply create an API on the server-side that accepts data requests and responds with the results in JSON.
In MVC terms. The server and client will both still use models, views, and controllers:
On the server (ie the Data API). The models are the database/storage access classes. Instead of generating raw HTML the views will be used to format/serialize data for transfer. The controllers work out the messy details between the models and views.
On the client (ie the WebApp client). The models are the functions that handle fetching and deserializing data requests. The views are your html partials that get parsed into static HTML. The controllers /directives manage combining the two.
Can you still do HTML generation on the server-side?
Of course. How much work you decide to do in the client vs server depends on your goals.
Then what's the benefit of client-side frameworks?
If your goal is to create a SPA, then frameworks like Angular are a much more robust option than the alternitives which would consist of firing off a bunch of AJAX requests, then plugging it into the DOM using something like jQuery.
What's so special about client-side frameworks?
Nothing really, they push the responsibility of HTML generation into the client. Instead of splitting HTML templating and dynamic manipulation between the client and server you can now do both in the client. It provides a cleaner separation of concerns and reduces load on the server.
If you need a data layer that can be accesses by multiple platforms (ex IOS, website, Android) then you've likely isolated the data requests into their own API already. If you have that done already, pushing the client-side code to the client makes sense since you're already doing that for the other platforms.
Simplifying the server to just a data layer makes life a simpler for those who develop on multiple platforms. Client-side frameworks made the process of fetching data and generating HTML dynamically on the client much easier. If your goal is to build a SPA, using a framework will provide a good scaffold to build on.
The major downside of client-side HTML generation is that it relies on JavaScript and most search engine webcrawlers are too dumb to use JavaScript. That means, if you have a content-heavy site you're going to have a bad time trying to get search engines to index your content. There are hybrid approaches to conditionally load content generated from the server to webcrawlers but they add another additional layer of complexity so the tradeoffs likely outweigh the benefits.
Best Answer
JSON/HTTP is a really good decoupling mechanism, and I'll throw out a couple of suggestions that will make it even more loosely coupled.
The rapid industry adoption of JSON/HTTP interfaces really speaks well about how people view the usefulness of that model.
That is, when parsing the JSON (client or server), the app MUST IGNORE any fields it don't recognize.
XML went in the with idea that the app MUST UNDERSTAND each field or else the document was invalid. But that created problems with versioning, because with almost any change, clients needed to upgrade every time the server did. Even adding an informational field broke the spec. With MUST IGNORE, the server can add new fields any time, and as long as it doesn't remove or change the meaning of other fields (see below). Existing clients can just ignore the new fields. Rather, they MUST IGNORE the new fields.
A search on MUST IGNORE and MUST UNDERSTAND will reveal lots of good articles that talk about that.
A "breaking change" is a change that will break existing clients. That is, removing a field the clients use. Or changing the meaning of a field (i.e. changing an amount field from dollars to Yen). That is, something that invalidates a client's assumptions about the data it's currently using.
With a breaking change, every client needs to make a change to support the new semantics or stop relying on missing fields. Do don't do that unless its necessary.
The next logical step gets kind of contentious -- but in the extreme you would never make a breaking change. That is, have full backward-compatibility for every release. That may or may not be realistic, and it may require carrying along baggage from early versions, but it will spare a lot of churn for the clients.
OAuth 2 is a really good bet for a well-thought out, standardized security protocol. You could sit down and design something simpler, depending on what compromises are OK. But OAuth is a good fleshed-out protocol that has undergone years of industry scrutiny, so they've had lots of time to work out the kinks. And standard libraries are readily available for both client and server. I used an OAuth plugin to DJango for one project and it worked out really well.
Because of the ubiquity of JSON parsers, maintaining a single API regardless of client will make life a lot easier. Sometimes it doesn't work out -- sometimes a client can only understand XML or some proprietary protocol, but starting simple & adding complexity makes life easier.