Proper directory structure for app versioning (Django) - django

I am currently starting work on a existing Django Project, and I need to make changes to the existing APIs. However, I can't change the existing code since old apps and sites have been using it, which might take a lot of time to change the structure, and might break current dependencies for those. So, for now, as asked, I need to maintain separate directories to change/review the existing code and achieve a versioning-like structure for Django apps. What might be the best way/structure to achieve this?
The current structure is simple as given by django-admin startproject
project_dir
|___project_name_dir
|___settings.py
...
|___app_1_dir
|___ __init__.py
|___ views.py, serializers.py
...
|___app_2_dir
...
So, I need to like create versioning type structure for app_1 here. What might be the best approach to do that?

You can create a new app, called api_v2.
But generally i put all applications inside an application folder in the project_name_dir:
project_dir
|___project_name_dir
|___settings.py
|___applications
|___api
|___ __init__.py
|___ views.py, serializers.py
|___api_v2
|___ __init__.py
|___ views.py, serializers.py
|___other_apps
|___ __init__.py
|___ views.py, serializers.py

Related

How to make models of app available to other apps in a django project?

It seems like to be best practice (or at least one common way) to create a Django 3 based fullstack project which uses project specific Django apps (instead of standalone Django apps) with a structure like this (refer to e.g. here):
fullstack_project/
frontend/
... # frontend stuff goes into here
backend/ # Django project name
apps/
app1/
apps.py
logic.py
models.py
...
app2/
apps.py
logic.py
models.py
...
wsgi.py
...
manage.py
The apps (here: app1) are integrated in the most basic form (no ruls, views, etc.) via fullstack_project/backend/apps/app1/apps.py
class App1Config(AppConfig):
name = 'backend.apps.app1'
and fullstack_project/backend/settings.py
INSTALLED_APPS = [
...
'backend.apps.app1.apps.App1Config',
'backend.apps.app2.apps.App2Config',
]
Using logic of one app (e.g. app2/logic.py) in another app (e.g. app1/logic.py) works just fine (e.g. via from backend.apps.app2.logic import ... in app1/logic.py).
However if I try to access the models of app1 in the logic of app2 I get django.core.exceptions.AppRegistryNotReady: Apps aren't loaded yet.. I could implement a database wrapper for an app to allow cross-app database access. However ass the apps are cross-project anyway I'd like to avoid that and allow access more easily. How can I fix this issue?
It is possible that there will be some code in __init__.py which is trying to access DB even before the app is registered and ready. so if you have any code in __init__.py comment it or make sure it will access database once the app is ready.

Is possible to customize the models package path in Django

The default folder structure of a project in Django is something like:
myproject/
- myapp/
- models.py
- myproject/
- settings.p
Would it be possible to change that structure?
I'd like to do something like:
myproject/
- myapp/
- infrastructure/
- models.py
- myproject/
- settings.py
or
myproject/
- myapp/
- infrastructure/
- models/
- __init__.py
- some_model.py
- myproject/
- settings.py
I know I can make a models package and split the models into different files. But I'm looking to change also the name/path of that package.
Yes and no. In that case, your app will be myapp.infrastructure and it will need to be added to INSTALLED_APPS in settings.
Having models.py file and models/ folder is mostly same for python. In this case, you will need to import different models in the __init__.py file inside the models/ folder.
The idea is that somehow your models and other codes should be imported somewhere in the project for django management command to see them (ex: for preparing database migrations - makemigrations command). So as long as makemigrations can see your model, you can place them anywhere. It is just a python's way, not directly related to django framework.
As for the name of basic things (models, views, apps, signals, admin and etc.) - I think the only one required to be in its name is models. As it is used directly by its name in ORM. Check this: Django Applications Documentation
So, it is possible thanks to python's syntax, but it is not recommended by django. Django's design practices were created to make it easier for everyone to write a readable app where you can easily understand where things supposed to be and work easily without learning internal rules of the project that someone else designed. It is very important for project where there are many developers and new members can join any time after the project's start. So, unless you are well aware what you are doing, you are free to develop any custom design you want - after all, all you need is for python to be able to import your functions and classes in other parts of the project.

django app file structure

Below is a common app file structure:
app/
views.py
forms.py
urls.py
tests.py
I found it's getting hard to maintain the code once the code base is getting big. I am thinking to organize the code based on individual web page, so each web page will have its own view.py, form.py and test.py.
app/
views/
page1_view.py
page2_view.py
forms/
page1_form.py
page2_form.py
tests/
page1_test.py
page2_test.py
Is there any big issue I will run into?
No. Django understands packages and files.
Example if you use
app/
views/
page1_view.py
page2_view.py
__init__.py
you can reference the views as app.views.page1_views without any issues.
The short answer is no. In fact, I've often split views, tasks, and tests as you are doing.

project layout and project utilities/libraries?

I am a bit confused with the project layout created since Django 1.4.
I want to add some global utilities to be used through my whole project and apps.
I tried to add a utils package at the same level of my apps but Django does not see it.
mysite/
manage.py
myapp/
__init__.py
models.py
mysite/
__init__.py
settings.py
urls.py
utils/
__init__.py
shortcuts.py
Any advice / best practice on how to use such a global utilities package ?
Thanks
Michael
Instead of adding it to PYTHONPATH which you have to do on each machine you install your project on, you can consider adding it to the django settings (mysite/settings.py) in INSTALLED_APPS variable:
INSTALLED_APPS=(myapp, utils)
This has the effect of adding utils to the python path, so you can do things like:
from utils import shortcuts

Django 1.4 project wide code ( template tags)

With 1.4 round the corner I thought I would give it a go but I have a question about the new project layout.
manage.py
myapp/
__init__.py
models.py
mysite/
__init__.py
settings.py
urls.py
I can see the logic here and I am a fan of the new layout however if I am having issues with adding project wide code.
For example:
I have created a new templatetag that is specific to this project and doesn't fit logically fit in any one of my apps. To me this should then fit within mysite however (as far as I can tell) this is not then processed. apptag.py (see below) is available but sitetag.py is not. Now, I am assuming this is because mysite not processed in the same way as an app(?).
manage.py
myapp/
templatetags
__init__.py
apptag.py
__init__.py
models.py
mysite/
templatetags
__init__.py
site.py
__init__.py
settings.py
urls.py
My question then is what is the right way to go about this issue? Should I create an app called 'core', 'mysitecore' or such like? I can add 'mysite' to INSTALLED_APPS but that just feels down right wrong. Or is there another option that I am missing here.
Thanks in advance.
Templatetags need to be inside an app that is included in INSTALLED_APPS. This is, in my opinion, a wart in Django that isn't fixed by the new layout. Your idea of using a core app - or, as I often do, utils - is the right one.