首页 > 解决方案 > 将整个应用程序映射到 Django 中的不同数据库

问题描述

我的 django_project 中有很多应用程序。其中之一是 user_interaction。我也在使用 2 个数据库。(Sqlite 和 MySQL)我希望我的 user_interaction 应用程序能够在 MySQL 数据库上完成工作。而其他应用程序应该在 sqlite3 上工作。事情是我希望在 MYSQL 数据库中发生 user_interaction 的所有读取、写入、保存、身份验证等。

其他应用程序的读取、写入、保存、身份验证等都发生在 Sqlite 中。

这是行不通的。所以我该怎么做?

settings.py 文件(数据库部分)

DATABASE_APPS_MAPPING = {'user_interaction': 'user_interaction_db',
                        }


DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    },


    'user_interaction_db' :{
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'FMS_Database',
        'USER': '#####',
        'PASSWORD': '#####',
        'HOST': 'localhost',
        'PORT': '3306',
        'OPTIONS': {
            # Tell MySQLdb to connect with 'utf8mb4' character set
            'charset': 'utf8mb4',
        },
    },
    
}

user_interaction 的 Models.py:

class StudentAccountManager(BaseUserManager):
 

    def create_user(self,username,password=None):
        # if not email:
        #     raise ValueError("Users must have an email address")
        
        if not username:
            raise ValueError("Users must have an username")

        user = self.model(
            username = username,
        )

        user.set_password(password)
        user.save(using=self._db)
        return user

    def create_superuser(self,username,password):
        
        user = self.create_user(
            password=password,
            username = username,

        )

        user.is_admin = True
        user.is_staff = True
        user.is_superuser = True
        user.save(using=self._db)
        return user   



class StudentAccount(AbstractBaseUser):
    username    =  models.CharField(max_length=50,unique=True)
    email       =  models.EmailField(max_length=254,unique=True)
    joined_date =  models.DateTimeField(auto_now_add=True)
    last_login  =  models.DateTimeField(auto_now=True)
    is_admin    =  models.BooleanField(default=False)
    is_active   =  models.BooleanField(default=True)
    is_superuser = models.BooleanField(default=False)
    is_staff    =  models.BooleanField(default=False)
    

    management_name = models.CharField(max_length=254)
    full_name = models.CharField(max_length=254,null=True)
    contact_no = models.CharField(max_length=10)
    department = models.CharField(max_length=254)
    residential_status = models.CharField(max_length=254)
    batch_year = models.CharField(max_length=4,default='Null')
    entry_qrcode = models.ImageField(upload_to = qrcode_directory_path,null=True)  
    

    USERNAME_FIELD = 'username'

    #specifying manager
    objects = StudentAccountManager()


    def __str__(self):
        return self.username
    
    def has_perm(self,perm,obj=None):
        return self.is_admin
    
    def has_module_perms(self,app_label):
        return True

user_interaction 的 Views.py:

    def student_registration(request):
        
        if request.user.is_authenticated:
            return redirect('/useraccount/studentuser/')
        else:
        
            form = raw_user_form()
            if request.method == "POST" :
                form = raw_user_form(request.POST)
    
    
                if form.is_valid():
                    save_obj = StudentAccount()
                    save_obj.full_name = form.cleaned_data['full_name']
                    save_obj.username = form.cleaned_data['roll_no']
                    save_obj.management_name = form.cleaned_data['management_name']
                    save_obj.contact_no = form.cleaned_data['contact_no']
                    save_obj.department = form.cleaned_data['department']
                    save_obj.residential_status = form.cleaned_data['residential_status']
                    save_obj.email = form.cleaned_data['email']
                    save_obj.batch_year = form.cleaned_data['batch_year']
                    save_obj.set_password(form.cleaned_data['password'])
                    save_obj.save()
                    return redirect('/useraccount/thankyoupage/')
        
        return render(request,'user_interaction/student_registration_page.html',{'user_form': form })

def student_login(request):
    incorrect = ''
    if request.user.is_authenticated:
        return redirect('/useraccount/studentuser/')
    else:
        if request.method =='POST':
            username = request.POST.get('username')
            password = request.POST.get('pass')

            user = authenticate(request, username=username,password=password)
        
            if user is not None:
                login(request,user)
                return redirect('/useraccount/studentuser/')
            else:
                incorrect = 'Incorrect username or password'

    return render(request,'user_interaction/student_login_form.html',{ 'message' : incorrect })

标签: mysqldjangodjango-modelsdjango-settingsdjango-database

解决方案


你需要的是一个 Django 数据库路由器。在这里查看示例。

假设您有这样的数据库:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    },


    'user_interaction_db' :{
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'FMS_Database',
        'USER': '#####',
        'PASSWORD': '#####',
        'HOST': 'localhost',
        'PORT': '3306',
        'OPTIONS': {
            # Tell MySQLdb to connect with 'utf8mb4' character set
            'charset': 'utf8mb4',
        },
    },
    
}

首先创建一个数据库路由器:

# db_routers.py
class AuthRouter:
    """
    A router to control all database operations on models in the
    auth and contenttypes applications.
    """
    route_app_labels = {'user_interaction',}

    def db_for_read(self, model, **hints):
        """
        Attempts to read auth and contenttypes models go to auth_db.
        """
        if model._meta.app_label in self.route_app_labels:
            return 'user_interaction_db'
        return None

    def db_for_write(self, model, **hints):
        """
        Attempts to write auth and contenttypes models go to auth_db.
        """
        if model._meta.app_label in self.route_app_labels:
            return 'user_interaction_db'
        return None

    def allow_relation(self, obj1, obj2, **hints):
        """
        Allow relations if a model in the auth or contenttypes apps is
        involved.
        """
        if (
            obj1._meta.app_label in self.route_app_labels or
            obj2._meta.app_label in self.route_app_labels
        ):
           return True
        return None

    def allow_migrate(self, db, app_label, model_name=None, **hints):
        """
        Make sure the auth and contenttypes apps only appear in the
        'auth_db' database.
        """
        if app_label in self.route_app_labels:
            return db == 'user_interaction_db'
        return None

这样,所有与user_interaction模型的操作都可以通过user_interaction_db

接下来,将您的路由器添加到settings.py

DATABASE_ROUTERS = ['path.to.AuthRouter',]

推荐阅读