Is it possible to run several unrelated sites with one Django instance? - django

Each site should have its own domain, database, settings.py, urls.py, views.py and so on. As far as I understand, it's impossible, but I don't quite sure.
EDIT: jdi suggests to use different settings files with different apps. Can you explain, please, how to do it?
Additional problem is that I use Webfaction and after selecting existing Django webapp receive following error:
Site app with this Site, Path and Account already exists
So I need to know, is it limitation of Django or Webfaction.
Version of Django is 1.3

This project structure is for Django 1.4, though the concepts remain the same
You can do all of that, just not with a single process. Create a single virtualenv for your project, which can store a shared set of every lib you need. Then create different settings files for each site, which each load different django apps, all located within the project:
djangoProject
|- bin/
|- include/
|- lib/
|- manage.py
|- djangoProject/
|- settings_site1.py
|- settings_site2.py
|- settings_site3.py
|- wsgi_site1.py
|- wsgi_site2.py
|- wsgi_site3.py
|- site1_app/
|- models.py
|- views.py
|- urls.py
|- site2_app/
|- models.py
|- views.py
|- urls.py
|- site3_app/
|- models.py
|- views.py
|- urls.py
settings_site1.py (example)
...
# or you could make multiple urls_siteX.py files in the root
ROOT_URLCONF = 'djangoProject.site1_app.urls'
...
INSTALLED_APPS = (
...
'djangoProject.site1_app'
)
wsgi_site1.py (example)
...
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "djangoProject.settings_site")
...
But to be perfectly honest... all of this is even much more easily accomplished if you just create a single virtualenv with multiple django projects. Then you don't have to much with segregating your apps:
projectEnv
|- bin/
|- include/
|- lib/
|- project1/
|- manage.py
|- project1/
|- project2/
|- manage.py
|- project2/
|- project3/
|- manage.py
|- project3/
Either way you do it, I don't think it is necessary to think about trying to get them all to run under the same single process. Django isn't designed to do that. It is designed to let you run multiple processes on the same project, for different sites, via the sites framework.

Related

Can I put custom settings in Django's settings.py

I have several custom settings I'd like to define in my Django app. Up to this point, I've put them in a constants.py file in each individual app.
myapp/constants.py
HOURS_PER_EVENT = 4
MAX_MEMBERS_PER_EVENTS = 150
MAX_EVENTS_PER_YEAR = 10
...
It just occurred to me I may be able to put these in settings.py and after a quick test everything seems to work fine. Is this allowed or is settings.py reserved for core django settings defined here? If it's not allowed, is there a better place to put these.
Yes it is allowed to extend your application settings, and it is really simple to do it. All that you need to do is a simple manipulation from your current project settings.py to a module settings.
Your file structure is probably like the following:
mysite/
|-- mysite/
| |-- __init__.py
| |-- settings.py
| |-- urls.py
| +-- wsgi.py
+-- manage.py
What you need to do is to change it to something like this:
mysite/
|-- mysite/
| |-- __init__.py
| |-- settings/
| | |-- __init__.py
| | |-- base.py <-- (this is your old settings.py)
| | +-- constants.py
| |-- urls.py
| +-- wsgi.py
+-- manage.py
This is a pattern described in this tutorial.

How can I store 3rd party package migrations in a Django project?

I'm using the page module in feincms and when I add extensions to my settings I'd like to be able to store the migrations in my git repo.
There is some documentation on migrations in FeinCMS, but it looks incomplete, and I'm not able to get this working.
The file structure I have is:
- app
- feincms_
- migrate
- __init__.py
...
...
settings.py
...
MIGRATION_MODULES = {
'page': 'feincms_.migrate.page',
'medialibrary': 'feincms_.migrate.medialibrary',
}
...
Ok, silly me. I needed a directory with an __init__.py for each module.
i.e.
- app
- feincms_
- migrate
- __init__.py
- page
- __init__.py
- medialibrary
- __init__.py
...
...
So to sum this up, in order to set the location for any module's migrations in Django, you have to specify a valid python path in MIGRATION_MODULES. This path can be anywhere you like, but you have to make sure that it exists.

Django-templates: share custom inclusion tag between apps

There is a lot of questions about finding templates, but I can't find anything related to custom tags.
I have following schematic project structure:
/
|- app1
| |- templatetags
| | |- my_helpers.py
| |- templates
| |- my_helpers
| |- my_tag.html
|- app2
|- templates
|- include
| |- inclusion.html
|- base.html
In my_helpers.py a simple inclusion tag is defined:
from django import template
register = template.Library()
#register.inclusion_tag('my_helpers/my_tag.html')
def my_tag(...):
...
app2/templates/base.html looks like this:
{% load my_helpers %}
... some markup ...
{% my_tag %}
{% include 'include/inclusion.html' %}
And here my_tag works just fine. But when I'm trying to use it also inside 'include/inclusion.html' (I've added a {% load my_helpers %} tag there), it fails with this:
django.template.base.TemplateDoesNotExist
TemplateDoesNotExist: my_helpers/my_tag.html
As I understand, it looks for templates only in current app. But why it happens only for included templates? And is it possible to make it work?
To achieve this you can take advantage of Django template loader's feature.
You can create your project structure like below--
|- templates
| |- common_templates
| |- my_tag.html
|- app1
| |- templatetags
| | |- my_helpers.py
| |- templates
| |- my_helpers
|
|- app2
|- templates
|- include
| |- inclusion.html
|- base.html
and your my_helpers.py can be like
from django import template
register = template.Library()
#register.inclusion_tag('common_templates/my_tag.html')
def my_tag(...):
...

Where to store static/template files in Django according to "Two Scoops of Django"

I'm a reader and a big fan of the popular book Two Scoops of Django.
The book is full of great ideas, but there is one which is not that clear to me.
The authors advice to create a static and a templates folder in the Django project root.
That template folder is meant for "site-wide templates" (stated at pag.24).
Plus at pag.162 they say that "templates should usually go into the root folder of the Django project... The only exception is when you bundle up an app into a third-party package".
They don't mention it explicitly in ch.12 but I guess it is good to create a folder for each app (with the same name as the app) in the templates root.
Let's suppose that in my icecreamratings Django project I have 2 apps:
flavors with 2 templates: new_flavor.html and details.html
profiles with 1 template: details.html
All templates inherit from base.html.
I guess they would suggest the following structure:
icecreamratings_project/
|-- ...
|-- icecreamratings/ # Django project root
|-- ...
|-- static/
|-- templates/
|-- 404.html
|-- 500.html
|-- base.html
|-- flavors/ # same name as app flavor
| |-- new_flavor.html
| |-- details.html
|-- profiles/ # same name as app profiles
|-- details.html
Did I get it correctly?
On the other hand, the Django official docs suggests to create a static folder in each app and, inside it, a subfolder with the same name as the app, like: my_app/static/my_app/myimage.jpg.
So we have 2 different strategies: a unique template folder and many static folders (one in each app).
Having two different strategies is clearly a bad choice.
So, what do you think of storing in each app a template and static folder?
Something like this:
icecreamratings_project/
|-- ...
|-- icecreamratings/ # Django project root
|-- ...
|-- static/ # site-wide static files
| |-- bootstrap/ # bootstrap source files
| |-- jquery/ # jquery source files
| |-- css/ # css files used by base.html (and others in templates root)
| |-- js/ # javascript files used base.html (and others in templates root)
| |-- img/ # img files files used base.html (and others in templates root)
|-- templates/ # site-wide templates
| |-- 404.html
| |-- 500.html
| |-- base.html
|-- flavors/ # an app
|-- static/
| |-- flavors/ # static files specific for this app
| |-- css/ # css files for flavor app templates
| |-- js/ # javascript files for flavor app templates
| |-- img/ # img files for flavor app templates
|-- templates/ # template files specific for this app
|-- new_flavor.html
|-- details.html
The django official doc does not suggest your to create a static folder in each app. Instead it prefer to store the static dir under the project dir.
Static file namespacing
Now we might be able to get away with putting our static files
directly in my_app/static/ (rather than creating another my_app
subdirectory), but it would actually be a bad idea. Django will use
the first static file it finds whose name matches, and if you had a
static file with the same name in a different application, Django
would be unable to distinguish between them. We need to be able to
point Django at the right one, and the easiest way to ensure this is
by namespacing them. That is, by putting those static files inside
another directory named for the application itself.
The official doc also answered your question about templates structure.
class app_directories.Loader
Loads templates from Django apps on the filesystem. For each app in
INSTALLED_APPS, the loader looks for a templates subdirectory. If
the directory exists, Django looks for templates in there.
This means you can store templates with your individual apps. This
also makes it easy to distribute Django apps with default templates.
The Two Scoops of Django is a great book. But you should read the official doc first.
About templates, as per Django official docs (https://docs.djangoproject.com/en/3.2/ref/templates/api/#loader-types):
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [BASE_DIR / 'templates'], #add this line
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]

why Django put application at the same level of my project folder?

since Django 1.4 (I think) django create a folder for my project when I start a project. Django add a folder for any application I created (with python manage.py startapp) at the same level of my project folder.
Project_name
|---project_name_dir/
|---application_dir/
`---manage.py
I really like the following folder structure:
Project_name
|---project_name_dir/
| |---application_dir/
| | |-- __init__.py
| | |-- models.py
| | |-- tests.py
| | `-- views.py
| |-- __init__.py
| |-- settings.py
| |-- urls.py
| |-- wsgi.py
| |---templates/
| | `---application_dir/
| `---static/
| |---css/
| |---font/
| |---img/
| `---js/
|---deployment/
|---documentation/
|---config/
`---manage.py
Because I have a folder with all my django files (project_name_dir/) and other directories for non django files.
So why Django put application at the same level of my project folder?
In Django, the position of the application directory is not considered. Django only uses the name of the application.
Thus, the position of the application is basically a matter of convenience of the programmer.
This is also the reason why two apps should not have the same name: even if they are imported in INSTALLED_APPS as
('app.app1', 'app1')
Django only concerns with the last part after the dot, i.e. app1.
So, in the end, you can use the directory structure you want, as long as the apps' names don't collide and you point to the app on INSTALLED_APPS. Because of this, if there isn't any special reason, you should put them on the project's root, like Django does.