okfn-brasil / jarbas

🎩 API for information and suspicions about reimbursements by Brazilian congresspeople
https://jarbas.serenata.ai/
296 stars 61 forks source link

Applying good patterns to project layout #28

Closed Leeaandrob closed 7 years ago

Leeaandrob commented 7 years ago

So, in many projects that I have seen the utilized structure is:

captura de tela 2016-10-21 as 13 41 16

Maybe this could to be a issue to fix it?

cuducos commented 7 years ago

TBH I don't remember why I got used to do it the way it's done in this project. But actually I remember @henriquebastos taught me this way. Unfortunately I right now I can't remember the rational for that.

What I'm about to say is my opinion, totally biased by this architecture I'm been using for a couple of months.

In spite of being a Django standard (and supported by books as Two Scoops of Django) I tend to find this architecture you're suggesting confusing: my_app and mysite (following your example) are modules placed at the same location within the project tree, but they are not the same thing (my_app is actually a Django app while mysite is… well… Django basics to run the site).

Again: totally biased β€”Β cognition is based on tradition, and my tradition is to do the other way around.

That said, unless anyone give me a better reason not to change, I agree that this is an issue that could be fixed: following standards is a way to be more welcoming for contributors β€” in other words, I still can see a good side in following standards I disagree with… 

luzfcb commented 7 years ago

@cuducos probably in the next release of Two Scoops of Django book, the suggested project layout will be changed to the layout we use now: https://github.com/pydanny/cookiecutter-django/tree/master/%7B%7Bcookiecutter.project_slug%7D%7D

I do not like the default django layout, or the layout proposed by Henrique Bastos, I prefer the cookiecutter-django project layout, because at least for me, it's better to separate the things.

for this layout work, you only have to make three small changes on:

the cookiecute-django layout looks like this

.
β”œβ”€β”€ config # contains all django project related configurations
β”‚Β Β  β”œβ”€β”€ __init__.py
β”‚Β Β  β”œβ”€β”€ settings # settings.py has been separated into four files: local.py, production.py, test.py all inherit from common.py
β”‚Β Β  β”‚Β Β  β”œβ”€β”€ common.py
β”‚Β Β  β”‚Β Β  β”œβ”€β”€ __init__.py
β”‚Β Β  β”‚Β Β  β”œβ”€β”€ local.py
β”‚Β Β  β”‚Β Β  β”œβ”€β”€ production.py
β”‚Β Β  β”‚Β Β  └── test.py
β”‚Β Β  β”œβ”€β”€ urls.py
β”‚Β Β  └── wsgi.py
β”œβ”€β”€ project_name # contains all project apps and templates
β”‚Β Β  β”œβ”€β”€ contrib
β”‚Β Β  β”‚Β Β  β”œβ”€β”€ __init__.py
β”‚Β Β  β”‚Β Β  └── sites # this override migrations of django.contrib.sites app
β”‚Β Β  β”‚Β Β      β”œβ”€β”€ __init__.py
β”‚Β Β  β”‚Β Β      └── migrations
β”‚Β Β  β”‚Β Β          β”œβ”€β”€ 0001_initial.py
β”‚Β Β  β”‚Β Β          β”œβ”€β”€ 0002_set_site_domain_and_name.py
β”‚Β Β  β”‚Β Β          └── __init__.py
β”‚Β Β  β”œβ”€β”€ __init__.py
β”‚Β Β  β”œβ”€β”€ static # all apps static files
β”‚Β Β  β”‚Β Β  β”œβ”€β”€ css/
β”‚Β Β  β”‚Β Β  β”œβ”€β”€ fonts/
β”‚Β Β  β”‚Β Β  β”œβ”€β”€ images/
β”‚Β Β  β”‚Β Β  β”œβ”€β”€ js/
β”‚Β Β  β”‚Β Β  └── sass/
β”‚Β Β  β”œβ”€β”€ templates # all apps template files
β”‚Β Β  β”‚Β Β  β”œβ”€β”€ 404.html
β”‚Β Β  β”‚Β Β  β”œβ”€β”€ 500.html
β”‚Β Β  β”‚Β Β  β”œβ”€β”€ account/
β”‚Β Β  β”‚Β Β  β”œβ”€β”€ base.html
β”‚Β Β  β”‚Β Β  β”œβ”€β”€ bootstrap4
β”‚Β Β  β”‚Β Β  β”œβ”€β”€ pages/
β”‚Β Β  β”‚Β Β  └── users/
β”‚Β Β  └── users
β”‚Β Β      β”œβ”€β”€ adapters.py
β”‚Β Β      β”œβ”€β”€ admin.py
β”‚Β Β      β”œβ”€β”€ apps.py
β”‚Β Β      β”œβ”€β”€ __init__.py
β”‚Β Β      β”œβ”€β”€ migrations/
β”‚Β Β      β”œβ”€β”€ models.py
β”‚Β Β      β”œβ”€β”€ tests
β”‚Β Β      β”œβ”€β”€ urls.py
β”‚Β Β      └── views.py
β”œβ”€β”€ requirements # contains all python dependencies 
β”‚Β Β  β”œβ”€β”€ base.txt
β”‚Β Β  β”œβ”€β”€ local.txt
β”‚Β Β  β”œβ”€β”€ production.txt
β”‚Β Β  └── test.txt
β”œβ”€β”€ requirements.txt
β”œβ”€β”€utility # contains all non-python dependencies and helper scripts
β”‚Β Β β”œβ”€β”€ install_os_dependencies.sh
β”‚Β Β β”œβ”€β”€ install_python_dependencies.sh
β”‚  β”œβ”€β”€ requirements-jessie.apt
β”‚Β Β β”œβ”€β”€ requirements-trusty.apt
β”‚  └── requirements-xenial.apt
β”œβ”€β”€ compose # contains docker and docker compose files
β”‚Β Β  β”œβ”€β”€ django/
β”‚Β Β  β”œβ”€β”€ nginx/
β”‚Β Β  └── postgres/
β”œβ”€β”€ docker-compose.yml
β”œβ”€β”€ CONTRIBUTORS.txt
β”œβ”€β”€ docs
β”‚Β Β  β”œβ”€β”€ conf.py
β”‚Β Β  β”œβ”€β”€ deploy.rst
β”‚Β Β  β”œβ”€β”€ docker_ec2.rst
β”‚Β Β  β”œβ”€β”€ index.rst
β”‚Β Β  β”œβ”€β”€ __init__.py
β”‚Β Β  β”œβ”€β”€ install.rst
β”‚Β Β  β”œβ”€β”€ make.bat
β”‚Β Β  └── Makefile
β”œβ”€β”€ env.example
β”œβ”€β”€ LICENSE
β”œβ”€β”€ manage.py
β”œβ”€β”€ Procfile
β”œβ”€β”€ pytest.ini
β”œβ”€β”€ README.rst
β”œβ”€β”€ runtime.txt
henriquebastos commented 7 years ago

The core rationale of what I do is:

  1. The repository directory is the root of all things and contains many things: the code, docs, utilities, contrib, etc.
  2. The django project directory should be one single Python package with all it's subpackages, submodules, and assets. It should be on the root repository directory.
  3. I follow most of the unix project layout for the surroundings: doc, man, contrib, etc. But instead of the src directory I use the project name.
  4. There should be as little directories as necessary, avoiding boilerplates to be used.
  5. I always start with a core app at the heart of the project to avoid spanning too many django apps upfront.
  6. Having many requirements can be a problem. I have only one. 2 at most if my test environment is too complex. My development environment should be equivalent to production to avoid deployment friction.

I use TDD, so refactoring is an assumed part of the evolution. So I trust that the inner layout will evolve as needed.

I also like both having static and templates dirs at the project root directory or using AppDirectoryLoaders. Many of my apps get factored out of the project as libraries, so that influences me on how I do it.

I hope this explanation helps somehow.

henriquebastos commented 7 years ago

Also I just noted the cookie cutter layout separates config from project code.

For me, personally, this is a critical no go.

There should be only 1 settings.py supporting many instances.

Django mixes project settings with instance settings. However with python-decouple one can easily extract instance settings to environment variables.

The main goal is to keep one concise tested codebase that can be seamlessly loaded into many instance: dev, local, stage, production, demo, playground, whatever.

cuducos commented 7 years ago

Many many thanks, @henriquebastos!

In fact your explanation made it clear for me: we have a lot of good reasons to argue for this architecture.

Personally this is my favorite β€”Β and now I understand why.

henriquebastos commented 7 years ago

Anytime, dear friend! :)

cuducos commented 7 years ago

Closing this Issue since: