Remix.run Logo
senko 16 hours ago

Some more Django recommendations from Frank Wiles of Revsys (Django consultancy): https://frankwiles.com/questions/starting-django-projects/

I'll add a few of my own:

* Set up the project using uv

* I name the django project "project"; so settings are project/settings.py, main urls are project/urls.py, etc

* I always define a custom Django user model even if I don't need anything extra yet; easier to expand later

* settings.py actually conflates project config (Django apps, middleware, etc) and instance/environment config (Database access, storages, email, auth...); I hardcode the project config (since that doesn't change between environemnts) and use python-dotenv to pull settings from environment / .env; I document all such configurable vars in .env.example, and the defaults are sane for local/dev setup (such as DEBUG=true, SQLIte database, ALLOWED_HOSTS=*, and a randomly-generated SECRET_KEY); oh and I use dj-database-url to use DATABASE_URL (defaults to sqlite:///sqlite.db)

* I immediately set up up ruff, ty, pytest, pre-commit hook and GH workflow to run ruff/ty/pytest

Previously I had elaborate scaffolding/skeleton templates, or nowadays a small shell script and I tell Claude to adapt settings.py as per above instructions :)

bodge5000 14 hours ago | parent | next [-]

I'll add one; Add shell_plus. It makes the django shell so much nicer to use, especially on larger projects (mostly because it auto-imports all your models). IIRC, it involves adding ipython and django_extensions as a dependency, and then adding django-extensions (annoyingly, note that the underscore changes to a dash, this trips me up everytime I add it) to your installed apps.

Saying that, I'm sure django-extensions does a lot more than shell_plus but I've never actually explored what those extra features are, so think I'll do that now

Edit: Turns out you can use bpython, ptpython or none at all with shell_plus, so good to know if you prefer any of them to ipython

el_io 14 hours ago | parent [-]

> mostly because it auto-imports all your models

Django does this by default now. Since 5.0 if I'm remembering it correctly.

bodge5000 7 hours ago | parent [-]

In the default shell? I've definitely started new django projects since 2023 and I seem to remember always having to use shell_plus for that, though maybe thats just become something I automatically add without thinking

Edit: Yep, you're right, wow thats pretty big for me

Izkata 6 hours ago | parent | prev | next [-]

> * settings.py actually conflates project config (Django apps, middleware, etc) and instance/environment config (Database access, storages, email, auth...); I hardcode the project config (since that doesn't change between environemnts) and use python-dotenv to pull settings from environment / .env; I document all such configurable vars in .env.example, and the defaults are sane for local/dev setup (such as DEBUG=true, SQLIte database, ALLOWED_HOSTS=*, and a randomly-generated SECRET_KEY); oh and I use dj-database-url to use DATABASE_URL (defaults to sqlite:///sqlite.db)

There is a convention to create "foo_settings.py" for different environments next to "settings.py" and start it with "from .settings import *"

You'll still want something else for secrets, but this works well for everything else, including sane defaults with overrides (like DEBUG=False in the base and True in only the appropriate ones).

seabrookmx 2 minutes ago | parent [-]

IMO this is an antipattern because having a python file for each environment means you have bespoke code for each environment that is difficult to test and easily diverges.

If you use OP's way (I do something similar using pydantic-settings) the only thing that changes is your environment vars, which is much easier to reason about.

graemep 13 hours ago | parent | prev [-]

> use python-dotenv to pull settings from environment / .env

I disagree strongly with this one. All you are doing is moving those settings to a different file. You might as well use a local settings file that reads the common settings.

On production keep things like API keys that need to be kept secret elsewhere - as a minimum outside the project directories and owned by a different user.

senko 9 hours ago | parent | next [-]

Sure, that works as well, for example on some deploys I set the settings in systemd service file. However, it's more convenient to just have .env right there.

> On production keep things like API keys that need to be kept secret elsewhere - as a minimum outside the project directories and owned by a different user.

Curious what extra protection this gives you, considering the environment variables are, well, in the environment, and can be read by process. If someone does a remote code execution attack on the server, they can just read the environment.

The only thing I can imagine it does protect is if you mistakenly expose project root folder on the web server.

advisedwang 8 hours ago | parent | prev [-]

That's something that python-dotenv enables. It can pull from environment, which you can wire up from k8s secrets or whatever is the case for your hosting.