multi-tenancy solution with django - python

I want to create a multi-tenant application where each tenant will have its own domain and database.
Domains will be like this: store1.saas.com, store2.saas.com .. and their respective databases will be store1 and store 2..
I have decided to name it as such so that depending upon on the url, i can set the database with some middleware.
I have tried https://github.com/bernardopires/django-tenant-schemas this but it wont work as it specifically asks to create a model inheriting from TenantMixin, which then is defined in settings like this.TENANT_MODEL = 'catalogue.Product'. I have multiple TenantModels and this scheme wont allow multiple models (it takes string and then uses split by "." and does their stuff based on it).
Trouble with me is
how to create sub-domains
how to test them in local, like store1.127.0.0.1:8000 wont work?

You could try emulating the future real world as close as possible by editing your hosts file /etc/hosts and putting in there:
127.0.0.1 store1.saas.com
127.0.0.1 store2.saas.com
... etc
Then you can navigate to your localhost by store1.saas.com and so on.

Related

How does a django project use multiple databases with the same structure to read and write, distinguished by url

I have a django project and want to divide it into multiple databases with the same structure.
Use url to distinguish different databases. When the admin management page logs in, log in to different databases according to different urls.
For example: 127.0.0.1/admin uses the admin database, 127.0.0.1/admin2 uses the admin2 database.
Does django implement this function? What do I need to do, Can you give me some suggestions or ideas? thank you very much
TL;DR
As far as a single django project is considered, there is no default way to achieve multiple database.
Scenario 1
From your very limited explaination I will assume that you want to seperate data of one admin dashboard from the data of second admin dashboard, to achieve data isolation with respect to permissions & other models, this is called multitenancy.
Very briefly: In a Multitenant architecture you can have multiple tenants whose structure is defined by your models.py and you can control all this tenant via a main superadmin, these tenants can have their own admin dashboard where the data stored in them are only specific to their tenant users. In more simpler terms you can have a SaaS app with this method, where you can have multiple organizations and these organizations have their own users with their specific permissions/groups.
Multitenancy can be achieved in django via a Schema seperated database using POSTGRESql and this awesome package that has already done most of the heavy lifting for you. You can achieve seperate logins via url or subdomain. If your tenants have users who part of more than one organisation and you want a single login for all of them then you can use this package that goes along with django-tenants. It provides a public user table with permission modules separate for each tenant.
Scenario 2
From your very limited explaination I will assume that you still want seperate databases for your app, in such case you need to rethink your approach to the problem because it is not something you will fancy after deployment as there is not direct way provided by django. Instead you should look into micro-service architecture.

Django personalized url

I need to use sub-domains (i think) on Django. I have many "room" on my project and i need to build url with name of room.
Example : If i have a room named "microsoft" and my domain is http://toto.fr i want to have a final url like : "http://microsoft.toto.fr" to go in room of microsoft. I can have few room then few differents url.
How its possible to have this ? Django Sub-Domains can do this ?
Thanks you !
About subdomains
I don't think there is a need in your case for subdomains. You can very well handle the separation of rooms this way:
http://toto.fr/microsoft/
http://toto.fr/room2/
http://toto.fr/room3/
The difficulty will increase (slightly) if you need to generate these urls (e.g users create new rooms).
Using subdomains
Reroute from Apache, Nginx etc.
This is the way I would go and recommend you.
Each service has its way of doing it so you would need to post a specific question related to the service you will use in production.
--- edit ---
The idea here is to have your urls.py work the way Django is meant to:
# urls.py
from django.urls import path
from . import views
urlpatterns = [
path('microsoft/', views.microsoft),
]
So this means on your localhost you will access urls that look like this:
https://localhost:8000/microsoft/something
This is how it is going to work behind the scenes. But you can setup your http server (Apache for example) to allow your users to use:
https://microsoft.example.com/something
Here's an example of configuration (disclaimer I am very much not an expert in this, this might not be exactly the correct syntax):
<VirtualHost *:80>
ServerName microsoft.example.com
RedirectPermanent / http://example.com/microsoft
</VirtualHost>
So when your user types https://microsoft.example.com/something, Apache knows it has to call https://localhost:8000/microsoft/something internally.
--- end edit ---
Use a django extension
django-subdomains does not seem to be active.
--- edit ---
Before going with third party code like django-subdomains you should always check if it is being maintained. You can see on their pypi page that it is not compatible with Django 2 and 3 (and therefore not compatible with python 3). So this should tell you to not go with it.
It would mean for you to start with components that are not being actively maintained and have potential security holes.
--- end edit ---
I tried very quickly to set it up with Django 3 and could get it to work.
There is the this fork that claims compatibility with Django 3 but seems pretty inactive also.
You can handle as many rooms as you want with a variable:
urlpatterns = [
...
path('foo/<str:theroom>/bar/', view_room, name="view-room"),
...
]
If for instance you access
http://youraddress/foo/ubuntu/bar/
then Django will call your view function
def view_room(request, theroom):
with theroom = ubuntu.
If you prefer defining subdomains like http://ubuntu.youraddress, you will have to define one subdomain per room in the httpd config file, but also, to declare these subdomains in an authoritative DNS. That might be complicated, and is not a good idea IMHO, since subdomains are rather used to specify which app is called.

Best approach for loading settings that can be modified in Flask

Hello all fellow StackOverFlow'ers,
I'm making an app in Flask that runs depending on settings that can be changed by administrator via a POST request in their admin-panel,
Actually, the only two things I came up with for doing this is using os.environ.get (Environment variables) [which i'm using now] or insert it to a PostreSQL Database config table and load it up
Anyway I will be storing settings such as a couple of API_URLs and their API_KEY, and some Conditions of checking like a success value where if condition in text .. else is applied to ... where admin can change them via the panel
I'm looking for the best performant approach for doing such thing.
Best regards.
If you're looking for the changes to only apply on a per-user basis (changes made by the admin only affect the admin), check out Flask's sessions. It works like a dictionary, but stores information in a cookie in the user's browser that can be programmatically accessed by Flask. Be warned that this data is stored in plain-text in the user's browser, so don't store anything sensitive here.
On the other hand, if you're looking for changes made by the admin to affect everybody visiting the website, you may just be able to store the settings in a variable, update them when the admin makes changes, and read them when responding to a request. If you want these settings to persist through a server restart, however, you'll need to write them to disk and then load them on server restart and save them to disk when they're changed. If this is a production-grade app and needs to be able to scale, I personally recommend using an SQLite file to store settings (or a SQL database if it really needs to scale), but this is a personal preference of mine. If this is just a personal app, storing settings in text files would be just fine.
Hope this helps!

rookie questions : code structure ,writing my own admin/auth/registration from scratch , global functions and variables

I'm a LAMP developer and i've just started learning/writing code in python/django ... i like it so far but i have problem with couple of pre-built in apps/components and i like to write them from scratch on my own .
most notably admin section AND authentication/registration
i have lots of reason for that but mostly because my native language is not english and the END USER doesn't speak any.i dont like the way admin looks and represents the data , i like to use ajax for most of my forms , i need lots of extra functionality in admin which django doesn't offer out of box and i don't like to hack into it and ...
so with that in mind i'm going to ask my questions
1 - how should i structure my admin section ?
admin section basically has the same apps as the user section but with different functions so ,
should i add those functions in the same view as user functions ?
can i make like 2 views in a app ! or a sub directory containing admin view in each app ?
or create a directory in the root and copy all the apps there for admin ? ( the last resort would be split them in 2 different websites with the same app and put them in 2 host on the same server )
basically 2 websites (1 for admins / 1 for users) using 1 database
2 - auth/registration , i want to write my own code for handling these mostly becuz i dont want my admins and users to be stored in the same table(in database) also they have different columns and different data needs to be stored on registration
i've seen django contrib.auth in action it seems nice and easy , but can i easily modify it to have 2 different sets of login/register form working with 2 different tables?
if not i have to write my own code , so i have this sub-questions ( i like to know answer to these anyway)
2-1 i need to check if users is logged and if so read it from database on every view , how can i make a function run before every other functions in any view ?
something like
from .models import user
def currentUser(request):
thisUser = user.objects.get(id= request.session.get('user_id') )
can i run currentUser function on every reques and make thisUser available like a global variable to every other function/variable ( i guess i can somehow attach it to request which is passed on to every other functions in views ) or should i switch to use classes for views and solve this by inheritance/constructor function
2-2 the basic mechanic of authentication on other technologies (im a LAMP developer) is to store logged user id in a session and in each httprequest check that session to see if contains user id if so he/she is logged and would be red from database and if not user is not logged ... is there anything different in python/django that i should know or it's the same here ?
2-3 if i create 2 different app that work with the same table(database) for example auth app for registration and login , user app for editing user information and other stuff
what is the right/preferred way to create models ? should i define them in 1 app like user app
user/models.py
class user(models.Model):
username = models.CharField(max_length=20)
name = models.CharField(max_length=100)
and include them on the auth views ?
auth/views.py
from .models import user
def login():
loggedUser = user.objects.get(username=request.POST['username'])
if so does authapp needs a model at all ?
There are a lot of Django admin plugins that exist. Some might do everything you need or only require minor modification. If you still want to write your own from scratch I suggest you study a few of them to get ideas. Check out this page for a good list.
As for the specific things you want to accomplish those are more specific questions than "what is best" format. I suggest you try to implement it and open a new question when you run into trouble.
I will help you with the first question by saying I have never been a fan of two sites for frontend/admin and even Django admin agrees by name spacing everything under the url /admin so routes don't collide.
Also the second, use the Django auth and simply extend it to do what you want. It ties into a lot more than you think. Admin/user accounts in the same table is not inherently a risk, separating actually requires more code which is where risk is introduced.
The last thing you want to do when adopting a framework is to immediately start throwing away huge parts of it. Try to get it to do what you want, then customize. I am sure you will find the framework to be malleable to your needs.

When should I use the Flask.config vs. use flask.session?

Is there a rule for when to use Flask.config vs. flask.session to store variables?
Anything that is static, app-wide, doesn't change much, and has important information for all users, should use config. (e.g. secret keys, options to modify the app from project to project, emails, generic messages)
Session should only be used to store relevant user data as the data is modified through each page. (e.g. user login data, user preferences, user inputs from previous pages)
If you have to save something from Page 1 to Page 5 in your website for that particular user, then use session. Sessions should mainly be used based on the individual user.
Yes, most definitely.
The config is for global, project-level variables: the location of files, keys for any APIs you might be using, your database access settings, things like that.
The session is for variables related to the current user's session on the site: their previous choices on a multi-page form, preferences, login details, etc.
You definitely don't want to get these mixed up.

Categories