Django v2+ how to properly use AppConfig for reusable apps - python

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?

Related

Should templates, views, and models go in the Django config app?

Is it considered against Django "best practices" to place templates, views, or models inside the Django config app? (The same app with settings.py)
Templates are probably a "no" because template files in a templates directory under the config app will not be found by default, I had to add a django.template.loaders.filesystem.Loader to load them.
Thank you for any advice.
There’s no restriction that a project package can’t also be considered
an application and have models, etc. (which would require adding it to
INSTALLED_APPS).
https://docs.djangoproject.com/en/1.11/ref/applications/
Its normally a good practice to leave your project directory as such and keep the apps in their own separate directory and have them defined in the settings.py. This will make your project much more organised and easy to maintain.

Run some initialization code when Django (1.9) loads

I saw that from 1.7 there is https://docs.djangoproject.com/en/dev/ref/applications/#django.apps.AppConfig.ready, however this is per each app.
What I am looking for is a way to call some initialization code when Django is loaded, regardless of which apps it contains.
Many people suggest adding the code to wsgi.py, urls.py and settings.py, however all these methods are 'dirty'.
My scenario is that I have several apps that could be part of the Django deployment, and I would like any subset to have this init code.
I could write a special common app, but I assume there must be a Django way of providing init code.
In newer versions of Django, you generally have a project directory containing the global, app-independent files like settings.py and wsgi.py. You can add global initialization code to __init__.py in that directory.
Be advised that this code is run very early (even before the settings are loaded), so some parts of the Django API are not available yet.

Adding several apps to INSTALLED_APPS at once

I am working on an app, which requires another app to be installed. I can add it to my setup.py and it will install the other app too.
After installing my application, i need to add it to INSTALLED_APPS, but i need to add the external app too.
Is there a way to pass the other application implicitly?
What's the recommended way to handle that kind of dependency to avoid asking the users to add more than one app when it is required?
Without doing some strange hacking, there's no way to do this, nor should there be. The user should be aware of what they are adding to their project and what dependancies are required. Remember Django's design philosophy:
Explicit is better than implicit
Have a look at some of the following apps. They all require dependancies in the INSTALLED_APPS. They make it clear in the docs that the user has to add them to their project manually:
Django Zinnia
Django Admin2
Django Filer
Django Filebrowser
There is a library called django-autoconfig that lets you do this. You basically include an autoconfig.py in your app, and if your app is include in INSTALLED_APPS, it's autoconfig.py is loaded.
The file should look something like this:
SETTINGS = {
'INSTALLED_APPS': [
'external_app_1',
'external_app_2',
],
}
Read the docs for more information about ordering and more advanced stuff like that.

Django admin project distribution and management

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.

Django-Pinax : How do you use a pinax app apart from what you get with a pinax base project?

I am trying to understand Pinax and plan to use it in my next project.
I have started with a pinax basic project, and now I have something to go with runserver.
Now, I understand that I can customize the initial setup that I got from pinax and customize the profiles, themes, etc as per my requirements.
But is that all that pinax provides ?
I am very confused here, like I want to use the pinax phileo app in my project, so how does pinax helps me do that ?
My Effort :
I searched and found that I have to install it with pip install phileo
Then, add it to INSTALLED_APPS and use it as required.
But what did pinax do in this ?
Pinax has phileo featured on its website, but why ? Since I could have used it just like any other app on my non-pinax django project.
So, my question in a nutshell is :
What does pinax provide after a base project and default templates that come with pinax ?
Right, now it feels like pinax just provides a base project with some apps already working with some default templates. [ That's it ? ]
Then, what about other apps featured on pinax's website that do not come with base projects ?
Please, help clear up the confusion !
Update
My question is somewhat - What is the significance of pinax-ecosystem when we already have them listed somewhere like djangopackages.com ?
You seem to be assuming that unless all of Pinax is useful, Pinax as a project isn't useful. It was never the intention that Pinax be a single thing, all of which you use on a given project.
If all you find helpful is the project layout, that's fine. Pinax suggests a standard project layout (which you can use alone with pinax-project-zero).
If all you find helpful is the pinax-project-account (django-user-accounts and a few other things, already integrated with templates following bootstrap class naming) as a starting point for you site, that's great. Pinax is fundamentally about getting you started sooner and pinax-project-account is a suitable starting point for most sites with user accounts.
Once you have a project, you are free to add any Django apps you want. There's nothing that requires you to use Pinax apps. "So", you ask, "why does Pinax even bother having apps?".
Well, because apps aren't isolated. Reusability isn't just at the level of app but also groups of apps. Take, for example, a waiting list app, an invitations app, a referral code app, a points app, a badges app. Sure these can be developed and used independently.
But if they are developed with the same mind set you can make sure the waiting list app and invitations app and referral code app work well with the user account app (and don't duplicate anything). You can make sure the referral code app plays nicely with the points app and the points app plays nicely with the badges app. You can make sure your forum app doesn't try to do something your moderation app already provides. Or that each app isn't trying to solve avatars its own way.
So Pinax isn't trying to be a "directory" of apps. It's a family of apps, themes and starter projects written with each other in mind.
Pinax is just django with a blend of other django plugins. You have to enable them and set them up individually. To use each individual app within pinax, you have to read that specific app's documentation and set it up appropriately (list of apps and repos which likely contain documentation here: http://pinaxproject.com/ecosystem/)
Some people like pinax but I find that its more of a hassel than a solution. In the end pinax doesn't work out of the box. You have to customize everything, but at the same time you position yourself into using a bundle you dont need. I suggest instead starting a project and installing the packages you need individually, and even finding more here: http://djangopackages.com/. Especially, if its a big project because then if you bundle/setup everything on your own you will know the ins and outs of it all.
The problem that pinax solves is that it avoids you hunting around for the best app that does something, as pinax bundles it together for you.
So if you want to get something up and running quickly, pinax makes that easy. For example, it is - by far - the quickest way to get a django project going with twitter bootstrap + other common plugins.
The benefit is simply this - when starting a new site, Pinax gives you a bit of a head start compared to an empty Django project.
Consider this: You're starting a new site that will need user account management (including email confirmation, user profiles, password reset, etc.), and notifications.
With Pinax, you can get this functionality in a few commands:
$ mkvirtualenv mysite
$ pip install pinax
$ pinax-admin setup_project -b basic mysite
$ python manage.py syncdb
$ python manage.py runserver
You now have:
Pretty much all you need for user management
All that stuff you always add to settings.py like PROJECT_ROOT
'About' Urls - (about / terms / privacy / DMCA / What's Next)
Django Debug Toolbar
i18n already set up.
Static files with compression when in production
A default theme (using Bootstrap)
A whole bunch of other stuff
From there, you can add apps and build / customize templates just as you would for any Django project. The difference is that you've just saved yourself a few hours of installing and configuring apps.
Regarding themes, they're trying to promote the idea of a theme as an app containing nothing more than static files. Take a look at the repo for the default theme to see how this works (it's basically just an app with static files and templates).
If you're a hobbyist building a single site which is your own project, don't bother with Pinax.
If you're a developer who is continually building new sites from scratch, Pinax may be your friend.
Pinax 0.7 was bundled with some apps and starter projects like social_projects which could be used for building a site more quickly, but I things changed in pinax 0.9.
I think pinax has reinvented its structure for some reasons (eg,In pinax 0.7 some people were complaining that it was messy to customize starter projects or to use only subset of certain starter projects so could pinax 0.9 provides more flexibility).
Some of the apps included in a pinax website are somehow coupled with each other so that it is easier to deploy them together,sometimes all you have to do is just installing them and the apps will communicate with each other.

Categories

Resources