> django vs DRF

It's not a "vs"; DRF is merely a library for Django thus requires Django. It gives you building blocks to create REST APIs and handles the boring stuff such as validation & serialization, pagination, rate-limiting, authentication, URL routing (in a RESTful manner), etc. If you need more than a few read-only API endpoints I suggest you go with DRF; it takes some time to learn the way it wants to do things but it's worth it in the end.

If all you need is to expose your models as a REST API, DRF will do that with pretty much zero code required, and in most cases that's enough. You can of course decouple your API structure from your models and write custom viewsets, serializers, etc but in this case you lose a lot of the built-in functionality of DRF and have to implement it all manually.

> react (or next.js) vs vue vs something else for frontend

Look at it from the perspective of the problem you're trying to solve as opposed to hype or frontend developers' career prospects.

Good old server-side rendered HTML (with ad-hoc JS or even jQuery where needed) can be good enough. The main advantage is that there's no barrier to entry, you grow as you go. Since you render the pages directly on the server you don't have to worry about providing API endpoints, then parsing that data back in JS, you just directly output it in the HTML.

If you do choose a single-page application approach, I suggest serving the SPA as static files from your Django app so that it is served from the same domain from the browser's point of view. This also allows you to mix and match SPA and server-side-rendered views (you can have your main app an SPA, but the login page - which is just a form and has no need for SPA features - can be server-side rendered for example).

In terms of which frontend framework to choose, I would advise against React as it's just a UI library meaning you need to (poorly) reinvent everything else such as URL routing, REST API clients, etc manually. Every React project I've been involved in had a custom, different, and differently flawed way of doing basic things like hitting a REST API even though it should be a solved problem (there's DRF on the server that can generate RESTful endpoint based on just a model, why is there no "JRF or JavaScript REST Framework" as a client-side equivalent?). I think Ember.js might be worth exploring as it's an MVC framework and should take care of the boring stuff so you can focus on business logic. It looks like it has the concept of "data adapters" so provided your API has a consistent structure it looks like you can have a data adapter that'll automatically map it all back to JS replicas of your model classes and then be able to use it as an ORM of sorts (and have the network communication, serialization, pagination, etc abstracted away by the data adapter).

> what else is in your stack for CI/CD, rollbacks, db migrations, deployments, etc.

Django now has built-in migrations which is pretty good. Deployments and stuff is highly dependent on whatever target you're deploying to. One thing I could suggest is Dokku (https://dokku.com) coupled with a bare-metal server from OVH or Hetzner. It's basically Heroku but orders of magnitude cheaper and more powerful. Depending on your uptime requirements this might be good enough for production, but if not it's at least a good option for a staging/test environment.

Use Celery with RabbitMQ for background & scheduled tasks. Do not use the Redis backend for it even if it's technically supported - it can fail catastrophically with the workers thrashing on the same task over and over again (speaking from previous experience having had to use the fire extinguisher more than once).

Use Sentry (cloud or self-hosted) for exception tracking.

> how you handle security / auth when using a front end framework with django as the backend -- are there any tricks?

Built-in Django auth is good if all you need is username/password auth. The django-registration package provides server-side-rendered views for registration/login. If you need social/federated login I suggest django-allauth which also provides its own views. For API endpoints you'll most likely need to roll your own login endpoint (with serializer) which takes a username/password, calls the auth backend(s) to check those credentials and then returns some kind of reusable token to the user (see below).

> I've heard JWT can cause headaches

JWTs (or other auth token formats) only come in play once you've already authenticated the user somehow (by them providing some secret info - most likely a username and password) and just want to give their client a way to reauthenticate without having to resubmit the same secret info again and again. You still need to actually handle that first part (see above). Once you actually authed the user and want to give them a token, then JWTs or similar come into play.

JWT's only selling point is that they can be validated statelessly without hitting a DB (they carry all the information you need along with a signature). This is mainly a benefit in microservices environments where some services might be completely stateless. In most Django projects you'd be hitting the DB to access the user model anyway (by accessing request.user for example) thus nullifying the sole benefit of JWTs. The rest of JWTs' features are just drawbacks is that it's extremely extensible meaning it's more complex than most projects need, and easy to screw up their validation or issuance, either from your side or even from the JWT library developer's side, thus I don't recommend them.

If you need to provide an API to browser-based clients, serve your frontend from the same domain as the API and use Django's built-in session authentication. On the login API endpoint, initialize the user's session (which will send a cookie back to the browser) and the browser will automatically send the session cookie for subsequent requests without your frontend ever having to do anything - all it needs to do is check for 401s and handle those by displaying the login view. As a bonus, any server-side-rendered views will also work out of the box.

For mobile apps, technically cookie-based sessions can also work, but common practice is to use some kind of bearer token. In this case, DRF has a very simple "Token" auth mechanism that just stores tokens in the DB and is good enough to get started. I suggest however extending that and making those "Device" models instead where you also store some device-specific metadata such as the push notification token, that way if you delete the auth token you implicitly delete the push token too and don't end up sending pushes to devices that are no longer authorized (seen that in production multiple times sadly). This also gives you a way to display to the user all the devices logged into their account and revoke them.

For the logins themselves something I recommend is to actually make your login page always server-side-rendered even if you use a SPA or a mobile app and render that page in a webview/iframe. This will allow you to easily change the login requirements later on (such as responding to brute-force attacks by adding a captcha, etc) without having to update the clients at all. That way you can swiftly react to new & constantly evolving security threats.