Question

I was thinking about packaging one of my django project into a reusable package.

How to package is given quite nicely at https://docs.djangoproject.com/en/dev/intro/reusable-apps/ and of course in many other websites.

What all these suggest is to include the re-suable app in your django project's INSTALLED_APPS list in settings.py.

Cool, but what I've multiple (3rd party) dependencies to the project. Should I tell in the documentation to include all those packages in the INSTALLED_APPS list!!

I feel that there should be a better way, that you just include one app and all it's dependencies are added to INSTALLED_APPS automatically by the app.

Now, let me give an example of clarity: (you may want to read from here)

  • project A: is a reusable django app
  • project B & C: are 3rd party django reusable apps used by project A (django-toolbar, reversion, etc., for example)
  • Project D: is your django project, and you want to include my project A in your app.

Now:

  • You could add 'A' in your INSTALLED_APPS
  • But you also have to add 'B' and 'C' as they are dependencies for 'A'

My question is: Is there a way, by which adding 'A' to your project include 'B' and 'C' automatically?

That being said, I know how to add custom settings and provide sensible defaults. It's only that, I'm not able to think my head over dependent apps problem (may be it's because it's going to be the next day now)

Was it helpful?

Solution

I nailed it with install_requires option in setup.py

We also have tests_require option and an extras_require directive which all goes to setuptools.setup() if you are using distribute.

  • install_requires and extras_require both are a list of requirements (packages).
  • extras_require is a dictionary with 'testing', 'doc' etc., are keys and a list of requirements as list.

These are added into distribute in version 0.5a4

Relevant links:

  1. All options
  2. extras_require

OTHER TIPS

  1. Project A: (with internal app: c and external apps: b):

    # Directory Tree:
    A
    ├── setup.py
    ├── a
    │   ├── apps        # internal dependencies
    │   │   ├── c
    │   │   │   ├── models.py
    │   │   │   ├── ...
    │   │   │   ├── app.py
    │   │   │   └── __init__.py
    │   │   └── __init__.py
    │   ├── core        # core library
    │   │   ├── __init__.py
    │   │   └── whatever.py
    │   ├── ...
    │   └── __init__.py # 
    ├── ...
    └── requirements.pip
    
    # File: A/requirements.pip
    # external dependencies: b
    
    b>=0.1,<0.2
    
    # File: A/setup.py
    setup(
        name="a",
        install_requires=["B",], # External Dependency
        ...
    )
    
    # File: A/a/__init__.py
    
    # to be added into INSTALLED_APPS later
    CORE_APPS = [
        "B",        # external apps
        "a.apps.C", # internal apps
    ]
    
    def get_core_apps():
        return CORE_APPS
    

    Project A may be designed as a framework/library without implementation. Thus it does not have wsgi.py, manage.py, etc.... But Project A could provide an example project (sandbox or demo project).

  2. Project D (Django Project): (with app: a)

    # File: D/requirements.pip
    a>=0.1<0.2
    
    # File: D/d/settings.py
    import a
    INSTALLED_APPS = [
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
    
        # ...
    
    ] + a.get_core_apps()
    

    Project D is an implementation of Project A. Thus it may contains settings.py, wsgi.py, etc....

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top