Django redirects app with development site - django

I have a Django application that exists with complete functionality in both a development and production environment. This is handled by just changing ALLOWED_HOSTS appropriately (assuming you don't want to DEBUG) and setting up Apache to serve each location properly. My issue is that I want to use the Django redirects app to handle my redirects moving forward (a part of this project is a transition away from PHP) because it means I don't need to deal with these redirects in Apache anymore. Redirects are a larger headache and Apache causes issues with its index.php redirect loops. Also this will allow me to transition more website control under Django, which is a goal for management ease. The problem I am encountering is the redirects app uses the SITE_ID to determine a valid target/redirect. The production server has a different hostname than development so I can not test or verify the redirects app. This obviously hurts the purpose of the isolated nearly-identical development server, which is to test all functionality before going live. I understand from the sites framework that individual sites need individual settings.py files and daemons to co-exists, but that again is not helpful to my scenario since the development site is geographically separate from production. It is not clear to me from the documentation:
1) How to add a site, other than adding/altering SITE_ID - where do I choose the associated name?
2) Assuming 1, is that the best way (and is adequate) since I already have a different settings.py file?
3) How did I end up with two sites entries for the same foo.com and how does this affect my redirects? I only have a single wsgi and settings.py (on each server) but
+----+-------------+-------------+
| id | domain | name |
+----+-------------+-------------+
| 1 | example.com | example.com |
| 2 | foo.net | foo.net |
| 3 | foo.net | foo |
+----+-------------+-------------+
in my database? I don't see where these sites are added or configured which is leading to my confusion about how to adjust my sites framework to fit the redirects app. Since I am on Django 1.5.4 the sites framework was enabled by default so I've never even thought about it before.

The name of the associated site does not matter since redirects just uses id, so I deleted all duplicate sites leaving just id 1 for the actual domain name, set SITE_ID = 1 in both production and testing configuration. I do not know where the other sites came from since I only used SITE_ID to set up redirects, but it works now.

Related

Self-hosting multiple sites via one Django project + apache - Django Sites framework

I have a self-hosted (raspberry pi) website running on Django - one project with several apps all serving on one domain name. I'm more of a programmer than a server admin, but it works! Now, I'd like to break one of those apps out onto a second domain name, but still hosting from my pi.
--I've looked into a lot of tutorials on how to do this as well as checked out answers like this one but the server-related instructions on everything I've found so far all go a bit over my head or don't seem to match up with my setup.
--I've tried the Django Sites framework and I've also followed this tutorial. While I was able to get my site objects in the db, all requests seem just to go to SITE_ID=1, regardless of domain name. I've seen conflicting information here about whether or not SITE_ID should be present in settings.py, but whenever I remove it, I just get errors about it (even though I do have the CurrentSiteMiddleware installed as well as a custom middleware like indicated in that tutorial).
Here's what I've got for Django (3.2.14, and py3.7.3), essentially:
DjangoApps
-mysite
--settings.py (allowed_hosts includes mydomain)
--urls.py (imports from app urls files)
--(etc)
-app1
--urls.py
--(etc)
-app2
--urls.py
--(etc)
-app3
--urls.py
--(etc)
and then the server confs:
/etc/apache2/sites-available/
-000-default.conf
-default-ssl.conf
-mydomain.com.conf [which points to the DjangoApps directory]
-mydomain.com-le-ssl.conf
I do not have an http.conf as mentioned in many of the tutorials/answers I've read through. I've seen some notes about using virtualenv and/or wsgi but I don't understand them, and I am requesting a more handholding step-by-step explanation of what to do here.
I assume this isn't the most optimal/modern way of doing this, but the key point here is that this main site is already live and working as-is so I'm really not looking to redo the whole thing. All I want to do is make it so that myseconddomain.com serves app3 only, and mydomain.com keeps serving everything (or, everything but app3, if that's easier).
Please help! And please let me know what other info is required.

Make django handle subdomain suffix

We're hosting several dockerized web-apps on our webserver, let's call it group.example.com. Our subdomains are handled via nginx as suffixes though, which translates to something like group.example.com/app1/ group.example.com/app2/ as root urls.
When using Django, we run into problems though, as all its urls generated by url in the templates such as home will be relative links, so rendered to home. This relative link will not be interpreted correctly, leading to the main, non-app page group.example.com.
So the goal is to have an app based prefix such as /app1/ for all links. I can hardcode these for static links, but there has to be a more elegant way. Also this leads to problem for the used forms submitting to the wrong page - redirecting again back to the main, non-app page group.example.com.
I tried adding /app1/ to all registered urls as prefix, but that doesn't seem to work either - that way the app is running but user would need to visit group.example.com/app1/app1/ to get to the index, and the relative links still don't work correctly.
In the app docker-container we're running the web-app with nginx and uwsgi. It works fine when using correct subdomains such as app1.example2.com - but we don't have that capability on our new faster webserver we want to host the app on.
Is there a way to resolve this using the app containers nginx, uwsgi or django / middleware config to get the links to resolve to group.example.com/app1/ as root?
As far as I know, there is two ways to resolve it.
One use SCRIPT_NAME in the NGINX configuration. For example, based on this server fault answer:
location /app1/ {
SCRIPT_NAME /app1;
# rest of the config
}
Two You can add FORCE_SCRIPT_NAME in your settings.py:
FORCE_SCRIPT_NAME = '/app1'
FYI, I would prefer using first solution.

Django-cms for multiple websites

How to setup a django-cms project to support multiple websites?
There's no reference to this in the official documentation and only limited information in the mailing list, but it's in the headline "A Django application for managing hierarchical pages of content, possibly in multiple languages and/or on multiple sites." and through the Django Sites Framework there's already built in support, and in the admin pages can be associated to different sites.
Related:
Django-CMS: Multiple domains on same project
there are a few different options to manage different websites (and, thus, templates and page contents) in Django-cms.
The basic approach
My favorite is probably the simplest:
In my virtualenv I have a single django-cms installation AND a single "project" that contains ALL the templates I use.
I have a global settings file plus one for each website that does only import all global settings and set "SITE_ID".
from base import *
SITE_ID = XXX
For structure i usually have a settings folder, an empty __init__.py inside, a base.py with all the common settings - including django-cms settings, and then the different websites eg. site1.py site2.py etc. (sometimes my structure is even slightly more complex to also account for dev/production, different machines, etc. but that's not relevant here).
I launch each website as a different instance - I use gunicorn so that's extremely easy too, each one of a different port.
I have an nginx fronted with a separate server configuration for each of my websites, and each of these points to a different gunicorn.
server {
listen 80;
server_name example1.com www.example1.com;
...
location / {
proxy_pass http://localhost:PORT;
}
}
Any of the gunicorn instances can access the admin, and all the data is shared in a single database, but for simplicity
That's all!
Of course it can be done similarly with Apache, mod_wsgi and different virtualhosts.
Advanced
Themes
I actually structured my folders to have an apps folder called themes. Each theme is actually an APP, though mostly contains only the templates and static folders, and it's added to the INSTALLED_APPS.
This allows for cute things such as inheritance and/or overriding between different themes.
Dynamic SITE_ID
It's also possible to use a middleware that will dynamically extract and set the SITE_ID from the URL. This allows to have one single instance... but I don't see any real advantage in this solution and rather find it a potential source of risks.

Hosting Django Project at /test #login_required redirects to /accounts instead of /test/accounts

I'm moving a project to new hosting and would like to set it up such that it sits at mysite.com/test/ (this is under mod_wsgi on an Apache server). This seems to do alright for the application itself, but when I use #login_required to enforce authentication Django redirects to mysite.com/accounts/login instead of mysite.com/test/accounts/login as I would like. I also have a mysite.com/prod that I want to do this same thing on so I don't want to hard code this anywhere in settings... it should figure out where the root of its URL is and act accordingly.
How do I set it up so that Django automagically redirects to what Apache considers that application's web root?
You need to set LOGIN_URL and LOGOUT_URL to full URL path in Django settings file. See:
http://docs.djangoproject.com/en/1.3/ref/settings/#login-url
Django doesn't automatically insert the mount point at the start of those as so have to be fully qualified.
The same problem can be solved in a more generic way for all project URLs. You could checkout an alternative solution at Running a Django site on my local machine, am I redirecting my URLs properly? for an environment based ROOT URL support.

django url scheme in apache and dev server

I have a a django application which is being served from apache/mod_wsgi under www.mysite.com/mysite
suppose I redirect url "myapp" -> myapp/urls.py
so to visit it from apache I will visit www.mysite.com/mysite/myapp/page1
to visit it from dev server I will need to visit www.mysite.com/myapp/page1
it also means absolute URLs wil be different in both cases
so what is the best way to handle this , so that app works same way in apache and dev server?
Don't embed absolute and/or non-computed URLs in your code or database. They will always come back and bite you on the ass.
Use either an alternate settings.py, or have some logic in settings.py to tweak differences between development/staging/production. We use settings.py as the production file and dev/staging use a local_settings.py which is tested for in settings.py and, if present, overrides production settings in settings.py. This prevents alternate development settings from creeping into staging/production.
Set a BASE_URL for the entire site and use it for everything else.
We go a bit further and have STATIC_MEDIA_URL and BIG_CONTENT_URL (for MP3s and Flash video) as the base URLs for other stuff.
All of this allows us to use whatever server is right for the moment. When I'm doing development I normally let the MEDIA come from the production servers (it's faster), but sometimes I'm doing a reorg of the media directories and I can't do it on production without breaking the world. So I just change my local_settings.py file to use my copy of the directories.