Django multitenant urls configuration - python

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

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

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.

Related

I get this error when I try to render some html files in django: NoReverseMatch at / Reverse for 'it_languages' not found

When I try to render a html file in django project, I get this error, and I can't see the localhost page 'cause of this.
The error is:
NoReverseMatch at / Reverse for 'it_languages' not found. 'it_languages' is not a valid view function or pattern name.
and it languages is url for in html
Then it bolds me with yellow this:
Home
About Me
**IT-languages**
Projects
Contact
I expect to see my offline page rendered by django project
Should I keep it like the original html version:
Home
About Me
IT-languages
Projects
Contact
Please start by providing your urls.py, views.py, and the it_languages template.
As #cbirch said, it's impossible to exactly provide an answer without more information (preferably the code they listed).
In general, the error 'NoReverseMatch' happens when you are trying to refer to an endpoint by the name, but the name doesn't map to a provided endpoint.
When you create a route you add an entry to the urlpatterns list in urls.py (typically) - if you don't give them a specific name, they will be given an automatically generated name. Then in your template file, if you refer to one of these names, they have to match!
Probably you use { url it_languages } or similar in one of your templates, but you haven't set that as a name for a url.
If you install django-extensions, there's a tool (show_urls) that will allow you to list your endpoints and their names (I believe) - that may help you trace the issue down. Good luck!

Flask and obtaining a full absolute path to a route

I'm looking to integrate some API's through a web application interface, to achieve this I need to identify the absolute path for a specific route. As I dont want to hard code any urls I'd like to do this dynamically in the flask app.
I thought that should be simple enough and tried a couple of things:
abs_url = url_for('home')
This didn't work of course as it just returned the route. I since learnt that url_for requires the function name. It then returns the route ('/home' for example).
I then tried:
abs_url = redirect(url_for('home'))
This gave me a redirect object, I was hoping path may be a variable I could call, however that doesnt seem to be the case.
Google has not been my friend today and hasn't given me anything to go on and advice would be appreciated.
The more I think about this the more I think the simplest option would be to capture the application address as part of the configuration.
To resolve this I have captured the application address as part of the initial info gathering form.

Flask: how to render view + add to database based on URL request path

I'm making a webapp with flask and SQL.
What I'm trying to do I can't seem to find the correct search terminology for:
I have my homepage at myapp/
I want to make it so when users add whatever path (myapp/whatever; myapp/hello) they will be rendered a certain view/blueprint (not redirected) and the name of the path ('whatever', 'hello') will be newly added to my database (unless someone has already opened it before)
I am sure this is a very common thing to do but I just cannot seem to find maybe the correct way to phrase it for google. I kind of found something about request.path which will give me the 'whatever'/'hello' part but I can't figure out how to piece the rest together.
Therefore, if someone could please either direct me with what to search, or if you know how to do it or have any resources, I will be very grateful. Thank you :) :)
What I understand what you're looking for is a route that accepts a keyword argument, creates a record in the database, and returns a template.
#app.route('/<path_name>')
def save_path():
# Do database insert here
return render_template('mytemplate.html')

Django urls.py, what does the name parameter do?

I was poking around my friends project and as I looked through the urls.py file i noticed this:
url(r'^apply/$', contact.as_view(), name='careers_contact'),
I just recently learned about class based views, and it all makes sense to me except for the last bit name='careers_contact'. I also can't seem to find the meaning of this online.
Can someone shed light on what this is, where that name lives, and what its doing?
url() name parameter
"What is it? Where does it live?"
url() is simply a function that returns a django.core.urlresolvers.RegexURLPattern object, so passing in a name='careers_contact' argument sets name for that object. None of that is really relevant until this url(...) is placed into a URLconf.
THEN, if we need the URL of a view, we can now get it by passing that name into {% url 'careers_contact' %} in templates or reverse('careers_contact') in code and on the backend those functions will use the name to map back to the correct URL.
Why do we need it?
We can reverse the Python Path to get the URL (ex. reverse(blog.views.home) ), so what's the point in using name?
URL Naming and Namespacing allow for 3 things:
A simple way to reverse URL match Class-Based Views. Though it is possible without it.
A way to distinguish URL patterns using the same view and parameters.
A way to differentiate URL names between apps.
(Click the links for an example of the issue and how naming/namespacing solves it)
The reason they probably added a namespace for the URL is so that they can do reverse namespaced URL.
For example in a template somewhere, you will probably see something like:
Click me!

How to configure the webserver to server a particular page as the default page?

I am using Lighttpd and Django. I have configured my Lighttpd server to pass all the requests ending with ".psp" extension to Django.
My startup page is a page served through Django, which is accessed as "http://192.168.1.198/home.psp". I want to enable the user to browse this page without writing "home.psp" explicitly in the url i.e. using "http://192.168.1.198"
Is this possible?
Thanks for any help in advance.
I think you're confusing concepts here between the "old" method of having individual files represent web pages which themselves contain code that is passed off to an interpreter before being sent in a response to how django/frameworks work.
If you're familiar with apache, imagine django as in part taking on the role of mod_rewrite. Django, and other frameworks, have what's called a dispatcher, or routing, mechanism.
Basically, they subscribe to the MVC pattern that says you should separate out the model, controller and view (in django parlance, model, template and view).
Now what then happens is you have a file called urls.py in django, which contains a list of routes (urls) and names of methods (usually contained in views.py) which handle them. Here's an example:
urlpatterns = patterns('',
url(r'^dologin$', 'testapp.views.auth_login', name="auth-login-uri"),
url(r'^doopenidlogin$', 'testapp.views.auth_openid_login', name="auth-openid-login-uri"),
url(r'^dologout$', 'testapp.views.auth_logout', name="auth-logout-uri"),
url(r'^login$', 'testapp.views.loginform', name="login-form"),
url(r'^openidlogin$', 'testapp.views.openidloginform', name="openid-login-form"),
url(r'^$', 'testapp.views.index', name="index"),
)
Here testapp is a python package, views.py is a python file and index is a django view. The url is constructed from regex, so I can have whatever I want as the url, much how stackoverflow urls are formed.
So basically, you never need file extensions again. I'd strongly suggest getting a good book on django - there are a few around.
What you might be looking for is the index-file.names directive in Lighty's configuration file. Just add "home.psp" to the list in your configuration file, and Lighty will look for it when no filename is specified.
I solved the problem myself. Here is what I did:
I had to add a statement inside url.rewrite-once block of lighttpd's configuration file like:
url.rewrite-once = (
"^(/media.*)$" => "$1",
"^(/static.*)$" => "$1",
"^/favicon\.ico$" => "/media/favicon.ico",
"^(/)$" => "/my_project_dir/home.psp",
"^(/.*)$" => "/my_project_dir$1",
)
Apart from this, I added the following line in my urls.py:
(r'^$',my_index_view_name),
Hope this helps someone in the future. Thanks everybody for your replies above. Cheers!

Categories