How to connect two django projects on two different servers
Problem: I am having a website which has various apps (Accounts, Community, Company, Payments, Main_project_app).
What I want is to set up a google type similar architecture where the userbase is on one server and other apps such as Gmail, drive, etc. serve the specific services on different servers based on the user authentication from the main Google userbase server i.e. Accounts app which have information about the user such as username, email, password, etc must remain on one server and using the REST API's or something we connect accounts app with another server to take the user from sign-in page to dashboard and serve them other services by using all other apps.
I am a newbie so please if I have done some mistakes to explain or something do correct me.
TLDR: django can not do cross database foreign key lookups, which is hard to solve as a beginner, therefore django may not be the right tool, or the approach of splitting the database has to be omitted.
As you probably can imagine your question goes very far in terms of creating a distributed system and as these systems have a million options of how you want them to function and how they are interconnected with a database cluster.
But I can try to give you an overview and the first problem you will be likely confronted with.
where the userbase is on one server and other apps such as Gmail, drive, etc. serve the specific services on different servers
Okay, from what I understand you want to split your database by model type. Specifically you want the User
model to be on a different database server with a different django instance doing authentication. This can basically be done by splitting the database locally.
Let us call the server with the User
database the AuthServer and another server the AppServer. The AuthServer must serve an API that receives user credentials and decides whether the user can log in or not. Meanwhile the AppServer needs to cache User instances locally so it must not reauthenticate the user on every request. That is easily done by implementing a custom AuthenticationBackend. Now the AppServer receives a login request, can pass it to the AuthServer and receive a user instance on success or not on login failure.
This works well even with relationships between User
and other app models because AuthServer and AppServer can use the same database server. But this somehow beats the purpose of splitting them up as you want to do it in the first place. Therefore django offers the approch of having multiple databases (the documentation here even uses that exact example that I will copy the code from). In your settings file you can store multiple database connections.
DATABASES = {
'default': {
'NAME': 'app_data',
'ENGINE': 'django.db.backends.postgresql',
'USER': 'postgres_user',
'PASSWORD': 's3krit'
},
'users': {
'NAME': 'user_data',
'ENGINE': 'django.db.backends.mysql',
'USER': 'mysql_user',
'PASSWORD': 'priv4te'
}
}
Further you can now write a DatabaseRouter
that will probably look something like this (incomplete example):
class AuthRouter:
route_app_labels = {'auth', 'contenttypes'}
def db_for_read(self, model, **hints):
if model._meta.app_label in self.route_app_labels:
return 'users'
return 'default'
def db_for_write(self, model, **hints):
if model._meta.app_label in self.route_app_labels:
return 'users'
return 'default'
For completeness you have to add the router to the settings
DATABASE_ROUTERS = ['path.to.AuthRouter', ]
Now the first problem you are going to have is if you want to connect the User model to any other model, which is extremely likely. Django does not allow to have cross database relationships in terms of foreign keys to models in other databases. You can circumvent the issue in a very complicated manner by using IntegerField
instead of ForeignKey
fields and care for the datasbase integrety for your self but I will no recommend you to do it.
After all django is not the right tool to do such widespread services if you are on a beginner level as you say, or you have to prepare for very complicated and bug and error prone xperience :)