0

I am trying to add some simple tenancy support to an app, creating an Account model which has a string 'tenant' to be read from the request url and identify the tenant in the system:

tenant.example.com/* -> www.example.com/tenant/* (rewritten by apache)

I wrote a simple middleware to capture this /tenant/ from request.path and add a request.account object to be worked with.

My problem is my url mapping.

I tried this:

url(r'^(?P<tenant_id>[\w\-]+)/', include('project.urls_tenant')),

and defined some simple urls inside urls_tenant.py:

url(r'^app1/', include('project.app1.urls')),

url(r'^app2/', include('project.app2.urls')),

When I try to access any page, I get an error message:

generic_view_method() got an unexpected keyword argument 'tenant_id'

because it doesn't (and really shouldn't) expect tenant_id as a parameter.

If I hardcode tenant_id in the urls.py file as /test_tenant/ everything works fine.

What am I doing wrong and how to fix it, so the request and the response gets processed normally?

Thank you guys pretty much. I used this as reference: optimal architecture for multitenant application on django

Community
  • 1
  • 1
oak
  • 137
  • 8

2 Answers2

0

If I understand your setup correctly you have defined:

url(r'^(?P<tenant_id>[\w\-]+)/', include('project.urls_tenant')),

In our main urls.py file and the other lines in your urls_tenant.py file ?

Taking it from there wouldn't any request that matches ^(?P[\w-]+)/ be passed through urls_tenant.py file ? The two lines you have defined there would only be able to match /app1 or /app2.

But I'm just guessing I'm not fully understanding your setup ?

I think it would be better if you would map the tenant url to a specific view instead of including a different urls.py file (I didn't even know this was possible).

url(r'^(?P<tenant_id>[\w\-]+)/', TenantView.as_view(), name="tenant-view"),

Something like the above looks more django to me.

Jonas Geiregat
  • 5,214
  • 4
  • 41
  • 60
  • Sorry, I didn't get your idea, nor why is it more django like... You are suggesting that I put the prefix in every url? – oak Sep 05 '12 at 17:22
0

You are capturing the named parameter tenant_id in the url pattern when you apparently don't need to. Try removing the parentheses to avoid performing the capture:

url(r'^[\w\-]+/', include('project.urls_tenant')),

This page is a generally useful read: https://docs.djangoproject.com/en/dev/topics/http/urls/#how-django-processes-a-request

Steven
  • 2,658
  • 14
  • 15
  • Yes, I think that will do, but how do I solve the consequential issue of `{% url some_named_url %}` producing `Reverse for 'some_named_url' with arguments '()' and keyword arguments '{}' not found.`? Thank you very much!!! – oak Sep 05 '12 at 17:20
  • 1
    Off the top of my head, 2 options: a) write your own `url` tag and `reverse` implementations; b) get rid of the apache rewrite and have your middleware determine the tenant based on the host subdomain directly, then you'll issue urls like /app1/news/latest/ which the browser will resolve against the correct subdomain. b) sounds better to me but I may have missed some issue with that. – Steven Sep 06 '12 at 07:54