I am working on creating a website in Django which consists of two parts: the website itself, and the forum. They will both be on separate domains, i.e. example.com and exampleforum.com. How can this be done in Django, when the forum and main site are part of the same instance?
This is done at the web server level. Django doesn't care about the domain on the incoming request.
If you are using Apache just put multiple ServerAlias directives inside your virtual host like this:
<VirtualHost *:80>
ServerName www.mydomain.com
ServerAlias mydomain.com
ServerAlias forum.mydomain.com
... other directives as needed ...
</VirtualHost>
This tells Apache to direct requests for all of those domains into the same instance.
For nginx your config file would look something like:
server {
listen 80;
server_name www.mydomain.com mydomain.com forum.mydomain.com;
... other directives as needed ...
}
Related
I use an Apache server for production with Flask as a WSGI app.
My Apache VirtualHost conf looks like this
<VirtualHost *:80>
ServerName mysite.com
ServerAlias www.mysite.com
...
</VirtualHost>
And my /etc/hosts file looks like this
200.110.100.11 mysite.com
200.110.100.11 www.mysite.com
I realized yesterday that my site was storing 2 different sessions for the naked domain and the www subdomain. So the user was logged out of www.mysite.com even if he was logged into mysite.com
After reading Flask docs, I figured that I had to set the SERVER_NAME config value and map the hosts file accordingly. So I set the SERVER_NAME config to mysite.com. But now I have a bigger problem. www.mysite.com/ started showing 404 after I set this value. However it is the custom 404 page I have set in my app, which means that the request is reaching my app, but it is not able to find a route. However mysite.com/ continues to work fine.
I chanced upon this thread https://github.com/mitsuhiko/flask/issues/555 and tried adding the line app.url_map.default_subdomain = 'www' to my init module and it only resulted in mysite.com getting a 404 now.
What am I missing here? I am not using Blueprints for my views as yet.
Am running with Python 2.7, Apache + mod_wsgi on CentOS 6.3
Things work fine when I am on localhost. However, when I run the code on a vm in Azure, I do not see the session information being persisted across pages.
Basically in my views, I have something like:
#frontend.route('/')
def index():
session['foo'] = 'bar'
print session['foo']
return redirect(url_for("frontend.page2"))
#frontend.route('page2')
def page2():
print session
The print output is:
bar
<SecureCookieSession {}>
My wsgi configuration for apache is:
WSGISocketPrefix /var/run/wsgi
<VirtualHost *:80>
ServerName example.com
ServerAlias example.com
WSGIDaemonProcess myproj threads=5 processes=5
WSGIScriptAlias / /home/mydir/myproj/apache/myproj.wsgi
<Directory /home/mydir/myproj>
WSGIScriptReloading On
WSGIProcessGroup myproj
WSGIApplicationGroup %{GLOBAL}
Order deny,allow
Allow from all
</Directory>
</VirtualHost>
I have the secret_key set:
app.secret_key = os.urandom(24)
I have tried with both setting SERVER_NAME but it doesn't help:
app.config['SERVER_NAME'] = 'example.com'
Any ideas on how I can debug this more?
Thanks!
Don't use app.secret_key = os.urandom(24)!
You're supposed to enter a static value here, not read from os.urandom each time. You've probably misunderstood the example in the docs, it shows you how you can read random data from os.urandom, but it also clearly states:
Just take that thing and copy/paste it into your code and you’re done
If you read it at runtime, then each of your worker processes will have a different secret key! That means if a request is handled by a different worker, the session will break because the cookie is signed with the wrong secret key.
I'm looking to have multiple domains and subdomains on a single Pyramid instance. However, I can't seem to find any documentation on it. The last question referred to a glossary with very little information and no examples. Do any of you have any examples or can direct me to better documentation?
Pyramid is just a WSGI application. This means it's dependent on the HTTP_HOST environ key (set by the Host header) to determine the host of the application. It's all relative. Point-being that Pyramid has no restrictions on what it can accept, thus the world is your oyster and you can set it up to limit content to various domains however you'd like. This of course starts with what hosts your webserver is configured to feed to your application.
Assuming you're using URL dispatch, you might want to design some custom route predicates that check the request.host value for whatever you'd like. Returning False from that predicate will prevent that route from ever matching a request to that host.
This is a large topic, so it might help if you give some more specifics. For example, since Pyramid is relative, any URL you may want to generate from 'example.com' to redirect someone to 'sub.example.com' will need to be done via a pregenerator.
def pregen(request, elements, kw):
kw['_app_url'] = 'http://sub.example.com'
return elements, kw
def req_sub(info, request):
return request.host.startswith('sub')
config.add_route('sub_only', '/',
custom_predicates=(req_sub,),
pregenerator=pregen)
config.add_route('foo', '/foo')
config.add_view(view, route_name-'foo')
def view(request):
# redirect the user to "http://sub.example.com", regardless of whether
# request.host is "example.com" or "sub.example.com"
return HTTPFound(request.route_url('sub_only'))
If you have control over your hosting environment, I would strongly suggest keeping the domain stuff out of pyramid and handling it with a proxy server such as apache mod proxy, routing to subdomains in pyramid. Then you can easily switch any of the domain name to view routing without having anything fragile (like domain names) in your pyramid code. Your app code will be much cleaner this way, and far easier to change later.
Here's an Apache example of two domains going to one pyramid app, assuming we are serving the pyramid app somehow or another on port 5001 (gunicorn or whatever you want).
<VirtualHost *:80>
ServerName domain_2.com
ProxyPreserveHost On
# send all request to our app at /app1/*
ProxyPass / http://127.0.0.1:5001/app_1/
ProxyPassReverse / http://127.0.0.1:5001/app_1/
</VirtualHost>
<VirtualHost *:80>
ServerName domain_2.com
ProxyPreserveHost On
# send all request to our app at /app2/*
ProxyPass / http://127.0.0.1:5001/app_2/
ProxyPassReverse / http://127.0.0.1:5001/app_2/
</VirtualHost>
And here's an example of one domain going to several pyramid instances:
<VirtualHost *:80>
ServerName mydomain.com
ProxyPreserveHost On
# admin go to manager app on 5001
ProxyPass /media/manager/ http://127.0.0.1:5001/ retry=5
ProxyPassReverse /media/manager/ http://127.0.0.1:5001/
# downloads from server app on 5002
ProxyPass /media/server/ http://127.0.0.1:5002/ retry=5
ProxyPassReverse /media/server/ http://127.0.0.1:5002/
</VirtualHost>
i am creating a django app, my project name is domain_com and the application name is gallery. The project is mapped to domain.com, so that works, now when i create the urls.py with these redirects its giving me these errors
(r'^domain_com/(?P<page_name>[^/]+)/edit/$', 'domain_com.gallery.views.edit_page'),
(r'^domain_com/(?P<page_name>[^/]+)/save/$', 'domain_com.gallery.views.save_page'),
(r'^domain_com/(?P<page_name>[^/]+)/$', 'domain_com.gallery.views.view_page')
error:
Using the URLconf defined in domain_com.urls, Django tried these URL patterns, in this order:
^domain_com/(?P<page_name>[^/]+)/edit/$
^domain_com/(?P<page_name>[^/]+)/save/$
^domain_com/(?P<page_name>[^/]+)/$
The current URL, edit, didn't match any of these.
any idea where the problem is? my intial install of django worked after create the application, so i am sure its the urls.py
this is my apache config
<VirtualHost *:80>
ServerName www.domain.com
ServerAlias domain.com
DocumentRoot /var/www/www.domain.com/htdocs/
ErrorLog /var/www/www.domain.com/logs/error.log
CustomLog /var/www/www.domain.com/logs/access.log combined
SetHandler mod_python
PythonHandler django.core.handlers.modpython
PythonPath sys.path+['/var/app/virtual/']
SetEnv DJANGO_SETTINGS_MODULE domain_com.settings
SetEnv PYTHON_EGG_CACHE /tmp
<Location "/gallery/">
SetHandler None
</Location>
</VirtualHost>
You have made a complicated URL of the form http://domain.com/domain_com/page_name/edit/. Yet you're testing with the URL http://domain.com/edit. Obviously, those don't match.
after updated my answer:
try this:
(r'^/edit/(?P<page_name>\w+)$', 'gallery.views.edit_page'),
(r'^/save/(?P<page_name>\w+)$', 'gallery.views.save_page'),
(r'^/(?P<page_name>\w+)$', 'gallery.views.view_page')
While urls.py is root folder of your application.
Then if you visit:
http://domain.com/edit/page1
it should work
Set up both your main root urls to include the urls of your apps: https://docs.djangoproject.com/en/dev/topics/http/urls/#including-other-urlconfs
Running Django 1.2.5 on a Linux server with Apache2 and for some reason Django seems like it cannot store CSRF or Session cookies. Therefore when I try to login to the Django admin it gives me a CSRF verification error upon submitting the login form. Has anyone come up against this and found a solution?
I AM able to make a valid post when i try this at the url of my VPS that was provided by my host. Example: vps123.hostdomain.com/admin/ and for that domain the cookies DO get set. However, when I go to www.sitedomain.com/admin/ and try to login I get a CSRF 403 error saying the cookie is not there and when I check in my browsers cookies they are not set.
I have tried setting the following in my settings file:
SESSION_COOKIE_DOMAIN = 'www.sitedomain.com'
CSRF_COOKIE_DOMAIN = 'www.sitedomain.com'
Also tried:
SESSION_COOKIE_DOMAIN = 'vps123.hostdomain.com'
CSRF_COOKIE_DOMAIN = 'vps123.hostdomain.com'
I have 'django.middleware.csrf.CsrfViewMiddleware' added to my MIDDLEWARE_CLASSES in settings.py and there is a CSRF token in the form and it shows up in the POST.
I have cookies enabled. I have tried this on multiple browsers and machines.
There is a varnish proxy server sitting in front of www.sitedomain.com that I think may be part of the problem. Anyone with experience using proxy servers and Django may be able to shed some light on that.
My apache2 config:
NameVirtualHost *:80
<VirtualHost *:80>
ServerName www.sitedomain.com
ServerAlias www.sitedomain.com
<Location "/">
Options FollowSymLinks
SetHandler python-program
PythonInterpreter nzsite
PythonHandler django.core.handlers.modpython
PythonDebug On
PythonPath "['/var/www/django_projects', '/var/www', '/usr/lib/python2.6/dist-packages'] + sys.path"
SetEnv DJANGO_SETTINGS_MODULE project_one.settings
</Location>
<location "/phpmyadmin">
SetHandler None
</location>
</VirtualHost>
<VirtualHost *:80>
ServerName othersite.sitedomain.com
ServerAlias othersite.sitedomain.com
<Location "/">
Options FollowSymLinks
SetHandler python-program
PythonInterpreter ausite
PythonHandler django.core.handlers.modpython
PythonDebug On
PythonPath "['/var/www/django_projects', '/var/www', '/usr/lib/python2.6/dist-packages'] + sys.path"
SetEnv DJANGO_SETTINGS_MODULE project_two.settings
</Location>
<location "/phpmyadmin">
SetHandler None
</location>
</VirtualHost>
The problem was that I have a Varnish Proxy server in front of my site. Varnish was taking requests and stripping cookies from them. To fix this I had to have the company that is managing the Varnish Server add '/admin' to a list of exceptions so that cookies could be passed. Sorry I can't shed more light on how the Varnish process works.
Are you including the {{csrf_token}} in your form template?
<form autocomplete="off" method="post" action="{% url auth_login %}">{% csrf_token %}
{{form|as_p}}
<input type='submit' />
</form>
And including the middleware?
'django.middleware.csrf.CsrfViewMiddleware',
From your edit, at a guess, it might have something to do with the VirtualHost configuration in Apache (if your provider is using apache). Here is an edited version of one of my apache configurations.
<VirtualHost *:80>
ServerName www.domain.com
WSGIProcessGroup my-django-site
WSGIScriptAlias / /path-to-my-django-site/wsgi/production.wsgi
Alias /media /path-to-my-django-site/media
</VirtualHost>
It may be the case that the server name within apache has to match the domain name you are hitting the box at, along with the *_COOKIE_DOMAIN settings in your Django configuration. I'm not sure if you'll be able to change this though. Might be worth speaking to your provider if no other answers yield a win.
Are you updating your template data with the csrf info?
from django.core.context_processors import csrf
def index(request)
data = {"listitems": items}
data.updates(csrf(request))
return render_to_response('template.html', data)