I'm comfortable with fairly one-dimensional Django implementations, but now trying to understand the multi-sites-with-shared-stuff process.
I've read through the Django Sites Framework and many posts on the topic, but I'm not getting the basics of how to start a second site that uses the same database, but presents itself as at a separate domain name.
I have a very happy and by-the-book django site consisting of one app running in a project.
To use the parlance of the tutorials I began a project "mysite" with
django-admin.py startproject mysite
and then started an app "polls" with
manage.py startapp polls
Q1: Does the Sites Framework assume each site is a separate project or a separate app?
A second app 'polls2' within the project seems to make sense, but the settings.py where SITE_ID is defined seems to be a whole-project thing. Is there a means to make app-by-app settings?
A second proj 'mysite2' adjacent to 'mysite' would give me a second structure with its own settings.py and a separate SITE_ID, but then there seems a big violation of the "DRY" principle as I'd be duplicating many elements of the adjacent sister project.
Q2: Sounds like I'll need to redefine database models (models.py) into a many-to-many relationships for sharing data between sites. Does that just change the way Django accesses those tables, or will the existing site's database need to be rebuilt as well?
Your guidance on what the intended process for implementing the sites framework would be great and much appreciated.
Q1: Does the Sites Framework assume each site is a separate project or a separate app?
A Django website usually consists of multiple apps, so the "single app" approach wouldn't really work. But it's not helpful to think in terms of a separate project for every site either. The only thing that has to be separate for every site is the settings file.
Does having a separate settings file for every site is a violation of the DRY principle? Not necessarily. You can (and should) create a base settings file with common settings. You would then import them in per-site settings files.
For example in your project directory you could have three settings files:
base_settings.py
siteA_settings.py
siteB_settings.py
siteA_settings.py
and siteB_settings.py
would import all the settings from base_settings.py
.
The only thing you have to put in the per-site setting files is the SITE_ID
setting with an individual site id. All the other settings may be shared across the sites (base_settings.py
) or be specific to a particular site (siteA_settings.py
, siteB_settings.py
) depending on your individual needs. For example you can redefine the TEMPLATE_DIRS
setting in per-site settings, if you have seperate per-sites templates, but if the templates are shared across the sites you don't have to. The same with all the other settings - url structure, list of installed apps, etc.
You would then choose which site you want to run just by specifying the settings files. For example with the Django development server:
python manage.py runserver --settings=mysite.siteA_settings
or
python manage.py runserver --settings=mysite.siteB_settings
Q2: Sounds like I'll need to redefine database models (models.py) into a many-to-many relationships for sharing data between sites. Does that just change the way Django accesses those tables, or will the existing site's database need to be rebuilt as well?
Models that are just shared between the sites don't need to be modified, as long as all the objects are shared. Only in cases when you want to be able to control which object of the model appears on each site, you need to account for that by adding a relationship (Many To Many or a Foreign Key, depending on your needs) from your model to the Django's Site
model.
Doing that does indeed change the underlying database structure (as adding a Foreign Key requires an additional column in a database table for a given model, and adding a Many To Many relationship requires a whole additional table). The Sites framework itself also uses its own database table, so you need to sync the database after enabling it.
After you add the relationship you can easily restrict your query to objects intended for the current site - for example by using the CurrentSiteManager. On the other hand you still can access all the objects, using the default manager (i.e. the usual Model.objects
form of accessing the ORM).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With