Django .env: Different configurations per environment and environment variables

Video thumbnail

Let's talk a little about how you can have different configurations in Django and not just how to perform your first unit tests in Django. To put this into context: we installed Django Tailwind so we could use Tailwind CSS from within Django. The main advantage is that we'll be able to purge the CSS later and not have the entire library in the project, especially if we're not using it 100%.

That's exactly what we're looking for, which is why we don't use the CDN option.

Now, in some installations, I want to customize the NPM_BIN_PATH setting, although it can be any other setting. It's important to note that, depending on the environment, you may need to configure the previous setting or even leave it out.

Option 1: Configure according to the operating system

A first option—the one I like least—is to configure your environment by asking for the operating system:

import platform
***
if platform.system() == "Windows":
    NPM_BIN_PATH = "C:/Users/andre/.config/herd/bin/nvm/v23.11.0/npm.cmd"

This might be useful because I only have to specify the NPM path on Windows. On Mac, this line simply doesn't run and everything's fine.

But... if you're working on a team, for example, with five people, three of whom use Windows, you could run into problems. Everyone might have Node installed in different locations (even if they use Herd), or some might have it installed globally. So asking only for the operating system is very limiting.

It might be useful if you need to disable a service on Windows, for example, but it's not a scalable or flexible solution.

Option 2: Use environment variables (best)

The best solution is to use environment variables.

Just create a .env file in your project, like the one I already have here:

djangoshopping\.env

Y agregas tus configuraciones:

NPM_BIN_PATH="C:/Users/andre/.config/herd/bin/nvm/v23.11.0/npm.cmd"

You can also export them from the terminal, in Windows:

NPM_BIN_PATH="C:/Users/andre/.config/herd/bin/nvm/v23.11.0/npm.cmd"

In MacOS/Linux:

export NPM_BIN_PATH="<RUTE>"

And at the configuration level, it is no longer a fine value, but rather, we indicate that it obtains it from the environment variables:

djangoshopping\djangoshopping\settings.py

import os
***
- NPM_BIN_PATH = "C:/Users/andre/.config/herd/bin/nvm/v23.11.0/npm.cmd"
+ NPM_BIN_PATH = os.environ.get('NPM_BIN_PATH', None)

In my particular case, I define the variable on Windows, but not on Mac, because I already have it globally and Django Tailwind automatically recognizes it.

And this is extremely useful if you work in a team:
Each person can configure their .env variable according to their environment without breaking anything for the others.

For example, if someone's name is "Pepito" and their Herd path is different, they can set it without affecting anyone else.

If someone has Node installed globally, they simply don't define the variable.
And if they use Laragon or another environment, simply define the corresponding npm path.

More configurations with variables

Another advantage is that you can use this same approach to define other environment-specific settings.
Instead of having fixed values in your code, you just use os.environ.get(...) and that's it.

Custom Configurations in Django 

Video thumbnail

What we're going to want to do is be able to establish the key we have from PayPal and create them using a custom configuration. Nothing could be easier.

mystore\mystore\settings.py

PAYPAL_CLIENT_ID = '<YOURCLIENTID>'
PAYPAL_SECRET =  '<YOURSECRETID>'
PAYPAL_BASE_URL = 'https://api-m.sandbox.paypal.com' #'https://api-m.paypal.com'

The above configurations are the PayPal public/client and secret keys, which you must obtain from the PayPal developer portal presented above.

We also configure the base URL for development:

'https://api-m.sandbox.paypal.com'

And this would be the one we use in production, that is, to make real payments:

'https://api-m.paypal.com'

And references from the view:

mystore\elements\views.py

from django.conf import settings
***
def detail(request, pk):

   element = Element.objects.get(id=pk)
   return render(request,'elements/detail.html',
                 {'element': element, 'paypal_client_id': 
                  settings.PAYPAL_CLIENT_ID})

Conclusion

Así que ya sabes:

  1. Configuring by operating system works, but it's limited.
  2. Using environment variables is cleaner, more scalable, and more professional.
  3. It allows you to have a flexible environment, especially in shared projects.

The next step is to learn how to generate test data in Django.

I agree to receive announcements of interest about this Blog.

We talked about how to define environment variables in Django and Let's learn how to create our own configurations.

| 👤 Andrés Cruz

🇪🇸 En español