Inherit Django application (a set of apps) - django

I have an architectural problem.
My team have large Django DRF application (lets name it "portal-backend") combined of set of apps, not installed as a modules but created manually. The apps are: blogs, news, entries, adminapi, gallery, comments, events, ideas, microposts, reactions, moderation, profile, and so on (about 50 apps).
Now I need to make some kind of "inheritance", use this product as a "base" in other team, and allow them to make changes in their nested classes.
For example if they need to change class blogs.views.BlogViewSet, they can just inherit it by they own class.
The "base" application must be installed with pip (if possible) or pulled from git (it's a single repo)
So, the main portal-backend shouldnt be changed in other team, just used as a base and extended by inheritance
Ideally my existing application should became some kind of high-level framework to create other portal-backends on the base of it with required modifications and additions on top of it.
What variants I thought about:
Split whole application into app-modules, put it into separate git repos, and install each app as a pip module. This method requires lots of work and has a problem that all apps are linked to each other so all modules need to be installed or nothing would work
Create some kind of building system, where "base" application git-cloned to specific folder (maybe as a git-submodule) and working app (that developed my other team) imports all the modules from this folder, or patches PYTHONPATH somehow to make imports transparent. Then, it would be possible to import mentioned class BlogViewSet and inherit from it. This looks like some duct-tape-solution, and quite fragile in wolowing development.
What would be your advice?

Related

does django have lots of clash if not isolated

I'm very new to django and web dev in general. I'm following tutorial https://www.youtube.com/watch?v=n-FTlQ7Djqc&index=1&list=PL4cUxeGkcC9ib4HsrXEYpQnTOTZE1x0uc create a blog by 'The Net Ninja'. His django version is 1.x but I'm using 2.1
I have completed it and have successfully emulate it on my own by following along.
But I wanted to make another on my own.
After I created it the files in my static files(the pictures for background) are clashing with my previous project.
Now background photo of my new project shows in previous project (both projects have static files in similar named folder )
So am I supposed to use virtualenv and is this kind of clash normal??? please help
It depends on what you mean with "clash". If you configure both installations to point to the same static files location, then, yes, you might have some "clashes". You can just make them point to separate folders.
As for virtual environments, it's generally a good idea to have a separate one for each project. This way you can isolate your dependencies better. This is especially important if you're going to run different versions of Django concurrently where some third party apps might not work on all versions.

Deploying/packaging subsets of Django apps

We have a Django 1.10 project consisting of 7 apps (let's call them A-G).
The project is actually three different servers consisting of different subsets of the apps like this: A+F, A+G, A+B+C+D+E. F and G are not referencing or referenced by any other app except for A.
Is there a way to already group this on the Django project level? Maybe three projects, referencing apps from other projects? I could not find a way to do this without duplicating code.
Is there a nice way to only deploy the given subsets? We do have three different settings files for each subset, only including the wanted apps. But this wouldn't mean we only deploy the code for those apps of course. We may not deploy app D for example for the subset server A+F.
Sounds like the rightâ„¢ thing to do is to package each app {A,B,C,D,E,F,G} separately, i.e. a completely standalone version control repository, it's own setup.py and all, and then have each of your 3 'servers' be projects in their own right, each of which install the relevant dependencies from {A,B,C,D,E,F,G} and adds the relevant settings etc.

What is the best practice for Django project structure?

I would like to know if there is a best practice for the structure of Django projects.
In particular, where do you located the virtualenv folder for your project?
Do you think is better the following solution:
/myproject
/myenv
manage.py
/mysite
settings.py
urls.py
wsgi.py
__init__.py
Or do you think is better to have a folder with all environments, for example in the home directory:
/virtualenvs
/myproject1_env
/myproject2_env
...
/myprojectN_env
I like to use virtualenvwrapper to keep my virtualenv at the same place and easily access them. I can recommand you to use this :)
Features
- Organizes all of your virtual environments in one place.
- Wrappers for managing your virtual environments (create, delete, copy).
- Use a single command to switch between environments.
- Tab completion for commands that take a virtual environment as argument.
- User-configurable hooks for all operations (see Per-User Customization).
- Plugin system for more creating sharable extensions (see Extending Virtualenvwrapper).
I have no relation with this project, I just use it on daily basis and really like it. Hope it can help you :)
Yup, using virtualenvwrapper is the best practice to manage your project without interfering with your machine environment it's like creating your own environment or machine you can say.
I think Django has provide the best structure as we use daily without any interruption not even mentally and it's easy to handle, Everything is separated so well.
Yes and you can have many aaps under one project which may or may not be connected to each other depends on your requirement , configuration of all app under one project will be in settings.py which is in parent folder for all apps.
Basically it's awesome what they have provided.I will suggest you to use default hierarchy, doesn't matter even if your working with big or small project.

integrating third-party django apps and templates

I'm new to Django and fairly confused about how third-party apps are best integrated. In my (possibly naive) interpretation of DRY, I want to minimize copy/pasting not only my own code but other people's code as well, so I'm happy with, for example, the pattern of using contrib.auth as mostly a black box if I needed additional info on auth.User (by extending auth.User with a UserProfile object or inheritance). And this was how I imagined I'd use most third-party apps as well.
However, I quickly found out this was very difficult, so now I've resigned to having "copies" of all of my third-party apps living inside my project folder that are basically entire copies with minimal changes. The final straw was me wanting to add a basic blog (I settled on django-basic-blog) and needing to just change a single template, and I thought of no better solution than just making a copy of that app inside my project with the single template changed.
My questions:
in this specific case where I need to change just a single template, is this (copy the entire app over) the best I can do? If I just needed to change a single model I can keep the third-party app respectfully intact and do a model inheritance in my own app...
in general, this practice of copying the apps under my project and patching each a tiny bit feels crazily wasteful and dirty. It also feels like if I'm using a frequently-updated third-party app it will be a pain to sync the changes. Should I just learn to love the bomb or is there some obvious architectural pattern / Django-provided assistance I am missing?
You should not modify the code of 3rd-party modules, as it's hard to track the changes and it creates a mess with the same code copied into many projects. Typical solution is to have only one version of each third-party module in your python path, not in your project's dir. This single package can then be reused by all of your projects.
However different approach is needed for templates, as they often need to be modified on a per-project basis. That's why Django comes with settings.TEMPLATE_DIRS and settings.TEMPLATE_LOADERS.
TEMPLATE_DIRS specifies list of directories containing template files. TEMPLATE_LOADERS specifies the classes used to load templates. The loaders will be used in order they were defined and the directories will be traversed in order they were defined. So you can look for templates in your project's directory first and in other modules as a fallback.
So basically you do not need to copy the entire python module in order to change one template. Copy just the templates directory of that 3rd party module or even just the single template you want to change. If you'll put in the right place and add have the path in TEMPLATE_DIR Django will use it.

django -- application subdirectory site/app1/app2/app3

If you were to write an app for a site, but wanted to make the app plug&play so you can just drop it in any Django project, set the main URL and there you go, how would you do that if you wanted to keep all the other required utility apps included in your portable app.
Example:
site/
site/site-app1
site/templates/site-app1
site/util-app1
site/util-app2
site/util-app3
Note: that the site-app1 makes the use of all three util-apps. It works great in this manner. But now, you decide to send the app to someone, but just that app with all its dependencies.
If we could package and send the apps like this?:
site/site-app1
site/site-app1/template
site/site-app1/util-app1
site/site-app1/util-app2
site/site-app1/util-app3
Then you just send site-app1 and everything goes with it.
Is there a way to make portable with utility apps as subdirctories?
Note: the idea is that we don't want to send the whole project, but one site-app within
the project only.
There have been a few presentations about reusable django apps, so search around. These should get you going:
Developing reusable apps. pdf and video
Django Templates: The Power of Inheritance
The presentations #Gerry links to are good sources of general info. To answer your question more directly, there isn't a way to package one app inside of another one (EDIT sorry, this is just plain wrong. You can put one app inside of another one's namespace, and it works just fine. It's an odd thing to do though: you're implying that the one app is a part of the other one; if that's true they'd be easier to use as a single app. So I'd still recommend one of the below options). AFAICT your options are:
If possible, make those external dependencies optional (i.e. enhanced functionality if util_app1 is available, fallback behavior if it isn't). This is how many apps behave with respect to, say, django-tagging or django-mailer.
Roll all the functionality into a single app. Depending how much code you actually depend on from the utility apps, if the dependencies are absolutely necessary for your app to function, this might be the best option to make things easy on your users.
Package and distribute all the apps separately and note the dependencies both in the documentation and in the setup.py install_requires. If all the apps are independently useful, this approach may be best. If they aren't all independently useful, why are they all separate apps?
Django applications can be made portable by adhering to certain practices. Ofcourse, these are not mandated
Application Location
The convention is to add applications in an apps/ directory, and to modify the manage.py (and eventually the apache config) to include
import sys
from os.path import abspath, dirname, join
PROJECT_ROOT = abspath(dirname(__file__))
sys.path.insert(0, join(PROJECT_ROOT, "apps"))
Your directory structure will look something like
site
site/apps/
site/apps/app1/
site/apps/app2/
Templates
Templates are located in the templates directory in the application. The convention is not to force the user to copy them in any other location. Eventually the user can have global templates to override the ones in the application.
Settings
Keep all default settings in a local file within the app directory. The settings would be overridden by the global settings. The local settings file will have the following structure..
from django.conf import settings
def get(key, default):
return getattr(settings, key, default)
SETTING_1 = get('SETTTING_1', 10)
These conventions should cover most major issues.