Deploying/packaging subsets of Django apps - django

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.

Related

Inherit Django application (a set of apps)

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?

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.

How and where should I put a version number in my Django project?

I'm making a Django project consisting of several apps and I want to use a version number for the whole project, which would be useful for tracking the status of the project between each time it comes to production.
I've read and googled and I've found how to put a version number for each django app of mine, but not for a whole project.
I assume that the settings.py (in my case it would be base.py, because the settings are inherited for each environment: developmente, pre-production, production) would be the ideal file for storing it, but I would like to know good practices from other Django programmers, because I haven't found any.
Thank you in advance
I don't think I've ever needed to do this, but the two obvious choices would be either the settings file, as you state, or alternatively the __init__.py in the main project app.
You don't need it to relate to django, you can tag a commit in your source control to provide a marker of a particular version (as well as a separate branch for releases).
From the docs for git tagging
Git has the ability to tag specific points in history as being important. Typically people use this functionality to mark release points (v1.0, and so on).
You could use the same versioning number system as google if you so wish which relates to
year.month.day.optional_revision # i.e 2016.05.03 for today
Doing this would make it easier to track back to previous versions since it won't be overwritten in source code by newer version numbers.

Best practice for managing project variants in Git?

I have to develop two Django projects which share 90% of the same code, but have some variations in several applications, templates and within the model itself.
I'm using Git for distributed source-control.
My requirements are that :
common code for both projects is developed in one place (Project1's development environment)
periodically this is merged into the development environment of the second project (Project2)
the variations are not easily encapsulated within apps. (eg. there are apps. such as "profiles" which vary between Project1 and Project2 but for which there's also an ongoing common evolution)
both Project1 and Project2 have public repositories, so that I can collaborate with others
similarly Project1 and Project2 ought to have development, demo, staging and production servers.
however, the public repository is not on the same server in both cases. So, for example, when I'm developing in Project1, I want to be able to "push" to my github server, but not have Project2 stuff going there.
there are files such as local_settings.py which are completely different between Project1 and Project2, but should be shared between multiple developers of each Project
So what's the best way of managing this situation?
What would seem to be ideal would be something like a "filtered pull" where instead of .gitignore saying "ignore this file entirely", I can say "ignore this file when pulling from that repo" I couldn't see anything quite like that in the documentation, but might there be something like that?
Move the common code to its own library and make it a dependency of those two projects. This is not a question of version control, but a question of code reuse, design and eliminating duplication.
Considering it is a Django / Pinax site, with variants scattered around inside several different applications, I would not recommend using submodules.
The variants should be managed independently in project1 branch and project2 branch, removing the need to "filter" a gitignore result.
If you identify some really common codes, they may end up in a third repo you could then "subtree merged" to project1 and project2 repositories (the meaning of subtree merge strategy being illustrated in this SO answer)
You can use two different git branches for development. When you make changes in one that are common to the other, just git-cherrypick them over. You can push and pull specific branches, too, so that no one ever need know you're working on both of them at the same time.
I would try submodules: http://www.kernel.org/pub/software/scm/git/docs/user-manual.html#submodules
I would make a third repo where I would place the code that Projects share. Then Project1 and Project2 would have their own repo and they can pull from that "shared" third repo.
I think that your idea of "filtered pull" will make it difficult to mantein.

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.