On Aug 29, 8:50 pm, Erik Allik <[EMAIL PROTECTED]> wrote:
> For the iPhone templates issue, I'd set up two projects instead of one  
> -- one for regular browsers, one for the iPhone. Then I'd simply  
> redirect from the regular one to the iPhone one as needed. Although  
> this has the negative side effect of having more than one URL per  
> resource, but you could also customize content visibility.
>
> Same for the second example -- normally one project is set up per  
> domain.
>
> Erik
>
> On 29.08.2008, at 1:24, Greg Fuller wrote:
>
>
>
> > I would like a way to to adjust settings  based on information in the
> > http header.  I've seen a similar question asked before, but I don't
> > need all the django request object, just the http header information.
> > More specifically, user_agent, http_host, and path_info.
>
> > Here are two examples of the sort of things  I would like to do:
>
> > # use iphone template  if appropriate
> > if  http_header['USER_AGENT'].find('iphone'):
> >    TEMPLATE_DIRS = (
> >         os.path.join(cur_dir_path, 'template_sets/' +  'iphone'),
>
> > # set SITE_ID for MyOtherDomain.com
> > if http_header["HTTP_HOST"].find('myotherdomain.com'):
> >    SITE_ID = 2
>
> > Does anyone know if this can be done?

I am reasonably sure both of you could do what you want using
mod_wsgi. That is based on user agent map to different instances of
Django where only difference is the settings file that was used.
Importantly, in the process using the same host name and URLs.

I'll explain how to setup Apache configuration etc, but will not be
surprised if I loose you along the way. :-)

First off, for this example I'll use daemon mode of mod_wsgi. What we
will do here is create two distinct mod_wsgi daemon process groups to
hold the two Django instances. I'll show it as two single but
multithreaded processes (ie., the default), but you can change that.

  WSGIDaemonProcess config-1 display-name=%{GROUP}
  WSGIDaemonProcess config-2 display-name=%{GROUP}

With display-name option, these show separately in 'ps' output as:

   70  2802  2800   0   0:00.01 ??         0:00.01 (wsgi:config-1) -D
FOREGROUND
   70  2803  2800   0   0:00.01 ??         0:00.01 (wsgi:config-2) -D
FOREGROUND

Am then going to force the main interpreter in each process to be used
for handling any requests. This is actually to make it easier as need
to name the interpreter within the processes for next step.

  WSGIApplicationGroup %{GLOBAL}

What we want to do now is setup each of those two process with
different environment. Specifically, we want to set
DJANGO_SETTINGS_MODULE environment variable to be different for each.
Normally we do this in the WSGI script file, but we will only have one
WSGI script file and no way to determine what to make the setting when
WSGI script file is first loaded. What we instead do is use ability to
preload a script file when processes are started.

  WSGIImportScript /Users/grahamd/Sites/config-1.wsgi \
     process-group=config-1 application-group=%{GLOBAL}

  WSGIImportScript /Users/grahamd/Sites/config-2.wsgi \
     process-group=config-2 application-group=%{GLOBAL}

The options to the directive allow us to indicate a different file to
preload for each process.

For the contents of 'config-1.wsgi' have:

  import os
  os.environ["DJANGO_SETTINGS_MODULE"] = "site.settings1"

For the contents of 'config-2.wsgi' have:

  import os
  os.environ["DJANGO_SETTINGS_MODULE"] = "site.settings2"

To configure mod_wsgi to host Django application itself, would
normally have:

  Alias /media/ /usr/local/django/mysite/media/

  <Directory /usr/local/django/mysite/media>
  Order deny,allow
  Allow from all
  </Directory>

  WSGIScriptAlias / /usr/local/django/mysite/apache/django.wsgi

  <Directory /usr/local/django/mysite/apache>
  Order deny,allow
  Allow from all
  </Directory>

The WSGI script file would normally be:

  import os, sys
  sys.path.append('/usr/local/django')
  os.environ['DJANGO_SETTINGS_MODULE'] = 'mysite.settings'

  import django.core.handlers.wsgi

  application = django.core.handlers.wsgi.WSGIHandler()

but we don't want that, and instead we want:

  import sys
  sys.path.append('/usr/local/django')

  import django.core.handlers.wsgi

  application = django.core.handlers.wsgi.WSGIHandler()

The difference here being that we have dropped setting of
DJANGO_SETTINGS_MODULE as this was done from preloaded scripts.

As to settings1 and settings2, these would be in same directory as
where settings file would normally be. They could be a complete copy
of original settings files with each modified as per requirement, ie.
setting TEMPLATE_DIRS differently. Or you could do:

  from settings import *

  TEMPLATE_DIRS = "......."

That is import everything out of main settings file and just override
what you want.

Now, there is one final bit missing from all of this because if we use
that as is, the requests will actually be handled in embedded mode as
haven't delegated that requests actually be run in the daemon
processes. What we will now do is provide a dispatch routine so can
automatically select which daemon process is used for requests.
Configuration for that is:

  WSGIDispatchScript /Users/grahamd/Sites/dispatch.wsgi

The content of the dispatch script would then contain:

  def process_group(environ):
    agent = environ.get("HTTP_USER_AGENT", "")

    if agent.find("Safari") != -1:
      return "config-1"

    return "config-2"

In this example what it is going to do is return that 'config-1'
process group should be used if Safari web browser is used, otherwise
use 'config-2' process group. Obviously you do proper matching of user
agent string as appropriate.

Now, I used daemon processes and the dispatch script to make it more
obvious but in case you needed to complicated things based on headers,
but other things could be done instead which may be a bit simpler.

First off you could do away with the dispatch script. That is, don't
use WSGIDispatchScript. Instead should be able to use something like:

  BrowserMatch .* PROCESS_GROUP=config-2
  BrowserMatch Safari PROCESS_GROUP=config-1

  WSGIProcessGroup %{ENV:PROCESS_GROUP}

That is, use mod_setenvif to match browser instead of dispatch being
handled in code. Using mod_setenvif has less overhead.

Next thing that can be done is not to use daemon mode of mod_wsgi but
run both instances in embedded mode instead, in separate interpreters.
For this we drop the WSGIDaemonProcess directives. When selecting
based off browser, select application group in embedded mode instead.
Thus:

  WSGIImportScript /Users/grahamd/Sites/config-1.wsgi \
     process-group=%{GLOBAL} application-group=config-1

  WSGIImportScript /Users/grahamd/Sites/config-2.wsgi \
     process-group=%{GLOBAL} application-group=config-2

  BrowserMatch .* APPLICATION_GROUP=config-2
  BrowserMatch Safari APPLICATION_GROUP=config-1

  WSGIProcessGroup %{GLOBAL}
  WSGIApplicationGroup %{ENV:APPLICATION_GROUP}

Obviously all the Apache child processes would twice as fat, where as
with daemon mode just one process for each instance.

Thus, various ways to handle the dispatch, and also can choose to host
as different interpreters with embedded mode processes or direct to
different daemon mode processes depending on what you need. You could
even get more tricky by running primary instance in embedded mode and
delegating just the one for the special browser to daemon mode,
especially if not frequently used.

Anyway, that should give you a lot to chew over. :-)

Graham







--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To post to this group, send email to django-users@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-users?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to