I have core django admin project that when my customers purchase needs to be modified both in configuration and function. Each customer will have their own instance of the project installed on a different server. Currently I am using django apps to separate out the difference in clients and using settings.py to load the correct app for the correct customer.
So my questions:
Is there a industry standard/best practice/framework to customize configuration and functionality in django admin projects and distribute them?
What would be best to do is write your core project on one side, and store it in a repository (version control). Apart from that, write your sub-applications as requirements and store/track them on separate version control.
Then, to keep everything working together and keep it all integrated, what you should do is that for different functionality, write it all in the same app, but add special settings that change the app's behavior. These settings can be stored in an independent settings_local.py that is imported at the end of your settings file, making them installation-independent, and you keep in your settings.py those that are general to all installations.
Related
I want to implement a module-manager in Django where third-party modules can be installed through the django admin interface (without changing the code-base of the main project). Or it could also be a service that runs on top of django.
These modules should have the same capabilities as a django app. For example, defining models and views, making migrations, and interacting with other apps. Similar to how it works with the plugin-manager of Wordpress.
Is there a good way to do this? (and are there reasons why I should not?)
What is a Django app? According to Django Packages
Small components used to build projects. An app is anything that is installed by placing in settings.INSTALLED_APPS.
Generally speaking, here are the steps to have an app working in Django
Install the app
pip install app
Register the app in one's settings.py
INSTALLED_APPS = [
...
'app',
...
]
In some cases they'll require to sync the database. Such is the case with social-auth-app-django. Here you'd have to do as well
python manage.py migrate
In some other cases they require specific versions of Python, Django, ect, so that'd have to be taken in consideration too. Such is the case with Django REST framework which requires
Python 3.6+
Django 4.1, 4.0, 3.2, 3.1, 3.0
It's possible as well that apps are dependent on certain Python libraries. Then, one would have to install them too.
For a basic version of that, one wants to create a place to have a button to install an app as well as a model to store the app. The model will keeps track of specific variations with BooleanField.
More precisely, since we now know some apps require database sync, the app model will have requires_db_sync = BooleanField(default=False). Then, if that's true, when installing that app one will want to run at least steps 1, 2 and 3.
One will eventually want to do a thorough analysis of the existing apps and understand the different possible variations (dependencies, requiring DB sync, etc).
I work with WordPress too and this was a thought that came to my mind a few years ago. I didn't pursue it because for most apps I still had to go to the code and do various configurations.
To deal with that, WordPress plugins, like WPForms, come with pages where one does that configuration.
Since such Django app configuration pages for configuration don't yet exist, they'd have to be created as well.
Also, would be great to have a trusted agency with standards to validate an app as good to be in that system.
Lets say we have one django project that has two apps - FooApp & BarApp.
Each app talks to its own database. Meaning they both manage their own set of models. Is it possible to manage the deployments of these apps independently? It's okay for them to be deployed on same server within the same nginx process as long as I am able to make changes to the apps without bringing down the other as well.
I understand that these can very well be separate projects and they can communicate with each other using RESTful APIs. For my needs, I want to avoid that REST interaction for the time being.
The django documentation [here][1] describes a django project and django app as follows
Django project:
The term project describes a Django web application.
Django App:
The term application describes a Python package that provides some set
of features.
So if the app is simply a python package, and the django project is really the one that defines how these apps are managed via the settings module, then I suppose there is no straight forward way of accomplishing what I want. Or is there anything I can do?
TIA
[1]: https://docs.djangoproject.com/en/dev/ref/applications/
After Django's 8 part tutorial there is an additional "Advanced Tutorial" which gives a quick-start like approach into python packaging. Namely, moving the Django tutorial app "polls" outside of a Django project and preparing it to be pushed to PyPi.
While this information is useful and covers a bit more ground that Python's own packaging tutorial (e.g. the MANIFEST file to include static / template resources). It doesn't quite explain how to make an app reusable in the sense of configurable options.
For example, if the app has a runtime dependency variable my_bool, how one would open up setting this option for their reusable app.
My first instinct was AppConfig. However, subclassing AppConfig for this purpose isn't explained in the documentation.
One could assume that all the options / settable variables come from the main settings.py file and set defaults if not there... but that also isn't explicitly stated or recommended in any of the Django docs that I have read thus far.
For a reusable application I am making, I would like the user to be able to augment the app with their own data files.
Thus they would need to supply these files in a directory somewhere (with a specified, designated structure) and then tell my app where they are e.g. MY_APP_DATA_DIR="os.path.join(BASE_DIR, <location>)".
Where would such variables go in a reusable Django app?
Would one use a dependency like python-decouple to grab these values?
Most documentation simply tells you to add the name of each of your apps to the INSTALLED_APPS array in your Django project's settings. What is the benefit/purpose of this? What different functionality will I get if I create 2 apps, but only include the name of one in my INSTALLED_APPS array?
Django uses INSTALLED_APPS as a list of all of the places to look for models, management commands, tests, and other utilities.
If you made two apps (say myapp and myuninstalledapp), but only one was listed in INSTALLED_APPS, you'd notice the following behavior:
The models contained in myuninstalledapp/models.py would never trigger migration changes (or generate initial migrations). You wouldn't be able to interact with them on the database level either because their tables will have never been created.
Static files listed within myapp/static/ would be discovered as part of collectstatic or the test server's staticfiles serving, but myuninstalledapp/static files wouldn't be.
Tests within myapp/tests.py would run but myuninstalledapp/tests.py wouldn't.
Management commands listed in myuninstalledapp/management/commands/ wouldn't be discovered.
So really, you're welcome to have folders within your Django project that aren't installed apps (you can even create them with python manage.py startapp) but just know that certain auto-discovery Django utilities won't work for that application.
I am right now in the situation to plan the internationalization of a django project that contains mainly legacy code. The old project itself has different applications which have a strong dependency to each other, so it is hard to separate them. Looking at the time left it is impossible at all.
The main requirements for the internationalization are:
Having separate projects for each country
Each country will later have different templates
each country will introduce new features which other countries may want to use as well
the main old codebase will still be maintained and should work with new features/changes to the country projects
Do you have any ideas/setups to deal with the old code AND starting new projects with the dependency to the old code and new features? I would like to start a discussion about this.
Start by decoupling the components where possible, and convert the legacy code to (portable) apps if not the case already, and the legacy code should not live under the main project tree.
Any new features should be well documented and decoupled apps or generic libraries themselves, even if they override/interact/depend or even monkeypatch the legacy code. You want most of your project to live outside of the main project itself, and installable via pip as if they were 3rd party apps.
The main project tree should be not much more than the project main project templates, an urls.py, settings.py, any configuration/deployment templates and a fabfile, and any core apps that will be rarely customized.
Every localized customization should just be either "customization" apps themselves, or small tweaks to main project (that should be made in a reproducible way via fab, or any provider of your choice)
Needless to say, if every team can commit to the core project, a good git/hg workflow is essential, and use a central CI server with a good test suite.