Search code examples
djangogitarchitecture

How to manage different repositories for different clients with the same project?


Good morning, I have to manage a Django project where each client has small customizations, both in terms of apps and API endpoints. I would like to avoid having to manage too many branches for each individual customer. Some potential solutions I've come up with are:

First solution

In the .env file, add a field indicating the client CUSTOMER=customer1

#settings.py
#...
INSTALLED_APPS = [
    "django.contrib.admin",
    "django.contrib.auth",
    "django.contrib.contenttypes",
    "django.contrib.sessions",
    "django.contrib.messages",
    "django.contrib.staticfiles",
    "rest_framework",
    "rest_framework_simplejwt",

]

customer = os.getenv("CUSTOMER")

if customer == "customer1":
    INSTALLED_APPS.append('custom_customer1')

Second solution

Use various branches according to the client, with the various merge coming from master/main

develop --> master --> customer1_develop --> customer1_master


Solution

  • One solution to this problem is to set up your project as a reusable app (or a set of reusable apps). For example you'll create apps called myproject_component_a, myproject_component_b, etc. then for each customer you'll create a separate Django project (potentially with its own git repository) that uses these apps.

    In their settings you'll add your apps in like so:

    INSTALLED_APPS = [
        "myproject_component_a.apps.MyprojectComponentAConfig",
        "myproject_component_b.apps.MyprojectComponentBConfig",
        ...,
    ]
    

    To include the URLs you can do the following:

    urlpatterns = [
        path("a/", include("myproject_component_a.urls")),
        path("b/", include("myproject_component_b.urls"))
        ...,
    ]
    

    Any communication needed between the core apps of your project and the custom apps can be done using signals so that your core apps don't need to be aware about customer specific apps.

    Structuring your project this way would allow you to customize things for one customer without them affecting the other customer, for example a particular customer can decide to have URLs prefixed differently from what you might be doing for other customers, you can remove / disable certain parts of your project for them, add in custom apps, etc. all without affecting any other customer.