views:

92

answers:

3

I'm in a situation where I need to merge two Django apps into a single, re-usable app. Neither are particularly large, but they are certainly not trivial apps and to preserve readability / sanity I'm trying to keep the two apps separated to some extent.

I could set up each app as a sub-package (which would be a pythonic way to achieve this end), or I can stick to Django's conventions and split the functionality separately in each case.

A Pythonic 'sub-package' approach:

package
|-- __init__.py
|-- views.py
|-- models.py     # imports models from both sub-packages
|-- tests.py      # imports TestCase instances from both sub-packages
|-- etc.          # shared stuff
|-- a
|   |-- __init__.py
|   |-- views.py
|   |-- models.py
|   |-- tests.py
|   `-- etc.      # a-specific code
`-- b
    |-- __init__.py
    |-- views.py
    |-- models.py
    |-- tests.py
    `-- etc.      # b-specific code

Or to appease the Django gods more directly:

package
|-- __init__.py
|-- views
|   |-- __init__.py
|   |-- a.py
|   `-- b.py
|-- models
|   |-- __init__.py  # imports models from a and b
|   |-- a.py
|   `-- b.py
|-- tests
|   |-- __init__.py  # imports TestCase instances from a and b
|   |-- a.py
|   `-- b.py
`-- etc. # shared/additional files

While I'd lean towards the former at the moment (which feels a little lighter), my gut tells me that although both work (and both involve importing 'hacks' to conform to Django's structure) the best choice depends on the contents of a and b - specifically how much of the code is shared or app-specific. It doesn't feel right to be constantly repeating the __ init__.py, a.py, b.py pattern in every subdirectory!

I'm interested in knowing which would is more appropriate from people with more experience dealing with Python!

ps. I'm aware they could live as two distinct apps, but they are so inter-dependant now that I do feel like they should be merged! (even aside from the improved portability of a single Django app)

+3  A: 

Flat is better than nested.

A "composite" application, built from two peer applications is fine. It works well.

And it promotes reuse by allowing the two components to be "plug-and-play" options in the larger application.

Don't nest things unless you're forced to. The number one reason forcing you to nest is name collisions. You don't have that so you don't really need any nesting.

S.Lott
+1  A: 

I'm not an expert in python but I always like to seperate applications and other artifact out as much as I can.

I am following the approach that is described in this blog for my own django project and it requires a little bit of tweaking on django. It has served me well so far.

The direct link to the github project

Tao
Thanks for the link!
adamnfish
+1  A: 

In my projects I often want to organize views and tests somehow, so I use structure like this:

package
|-- __init__.py
|-- models.py     # models are in one file
|-- etc.          # shared stuff
|-- tests
|   |-- __init__.py
|   |-- tests_orders.py
|   |-- tests_clients.py
|   |-- 
|   `-- etc.
|-- views
|   |-- __init__.py
|   |-- orders.py
|   |-- clients.py
|   |-- 
|   `-- etc.

For bigger projects having view functions in one file is a pain (for me).

This is what works for some projects I am working on - hopefully someone find this useful also.

Lukasz Dziedzia