udo
udo

Reputation: 5180

how to handle common code in a django project which is used by multiple apps

diving deeper into django I came across the challenge to handle code which is not specific to 1 app but is shared/used by multiple apps.

I would not(!) like to store it as part of an app (to avoid app dependencies) but to have it in a specific place.

currently my best practice is to create a django app "shared" in which I place this code/functionality

so my project structure looks similar to this:

mysite/
    manage.py
    mysite/
     ...
    shared
     ...
    app1
     ...
    app2
     ...
    app3
     ...
    ...

is there a "django best parctice" or a more practical way how to handle this?

Upvotes: 8

Views: 4129

Answers (2)

djpanda
djpanda

Reputation: 895

My answer is inspired by the documentation found in the edx-platform github repository: inter-app-apis

Creating a shared app seems like a good idea. However, its hard to decide whether something really needs to be in a shared app in the early days of development of a project.

If you are sharing only a small set of functionality, rather than trying to completely pull the shared code into a separate app, what if you could make it easy to manage the dependency? One problem with creating any sort of dependency is that they have a way of going out of control and very soon you wont know what parts of an app does your caller depend on.

To address this, you could define a separate python module that acts as a proxy between the app that provides the shared code and the app that calls into the shared code. So if you want your app2 to use some function foo in app1, you don't directly call that function, but you write a wrapper function foo_api in a separate module (called api.py) within app1 which calls the function for you. All functions from app1 that is called by other apps would have to go through this single api layer.

By doing this, you are not eliminating the apps depending on each other, you are making it easier to find the dependencies of an app. And if you later find that there are many callers for a function, then you could think of extracting these into a separate reusable lib.

Upvotes: 2

miki725
miki725

Reputation: 27861

I usually do exact same thing what you are doing. Not sure if that is best practice however I've seen other people using the same approach. I like it because:

  • when the shared/core/etc app becomes useful in other projects, you can package it as reusable app which can be installed via pip in other projects
  • it does not interfere with existing apps in the project

The only note about packaging it as a reusable lib is that I would recommend to rename it to something other then shared. The reasons is that when you package it in PyPI lets say as my_django_utils, then you will have to change all your imports in all the projects. If you come up with a generic name now, then you can easily package it in the future without needing to change all your imports...

Upvotes: 5

Related Questions