Django Model custom User создает таблицу auth_user в базе данных моего приложения при использовании нескольких баз данных

Я создал новый проект с нуля. По умолчанию он использует пакет auth для управления пользователями и разрешениями.

Я хочу переопределить пользователя по умолчанию - используя AbstractBaseUser.

Создав миграции и выполнив их на моих базах данных, таблица auth_user находится в моей базе данных приложения - не в базе данных auth.

Является ли это ожидаемым поведением? Я ожидал - и хочу, чтобы таблица auth_user находилась в базе данных auth.

Создать проект

py -m venv venv
venv\scripts\activate
pip install django

django-admin startproject core .
py manage.py startapp acmeapp

acmeapp/models.py

from django.db import models
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager


class Foo(models.Model):
    foo_id = models.BigAutoField(primary_key=True)
    name = models.TextField()

    class Meta:
        db_table = 'foos'

class AccountManager(BaseUserManager):
    """
    The management class to handle user creation.
    """

    def create_user(self, username, password=None):
        if not username:
            raise ValueError(_('The Username must be set'))

        user = self.model(username=username)
        user.set_password(password)
        user.save()
        return user

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


class Account(AbstractBaseUser):

    """
    The custom user model.
    """
    username = models.CharField(max_length=40, unique=True)
    email = None
    USERNAME_FIELD = 'username'
    REQUIRED_FIELDS = ['access_platforms', 'access_missions', 'access_rule_sets', 'access_mdsr']

    objects = AccountManager()

    def __str__(self):
        return ''.join(c for c in self.username if c.isupper())

    class Meta:
        db_table = 'auth_user'
                

core/settings.py

DATABASES = {
    'default': {},
    'auth_db': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': BASE_DIR / 'auth_db.sqlite3',
        "TEST": {
            "NAME": "auth_db",
            'DEPENDENCIES': [],
        },
    },
    'acmeapp_db': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': BASE_DIR / 'acmeapp_db.sqlite3',
        "TEST": {
            "NAME": "acmeapp_db",
            'DEPENDENCIES': [],
        },
    }
}

DATABASE_ROUTERS = [
    'core.db_routers.AuthRouter',
    'core.db_routers.AcmeAppRouter'
]

AUTH_USER_MODEL = 'acmeapp.Account'

core/db_routers

from acmeapp.models import Account


class AuthRouter:
    route_app_labels = ['auth', 'contenttypes', 'sessions', 'admin']

    def db_for_read(self, model, **hints):
        if model._meta.app_label in self.route_app_labels:
            return 'auth_db'
        
        if model == Account:
            return 'auth_db'

        return None

    def db_for_write(self, model, **hints):
        if model._meta.app_label in self.route_app_labels:
            return 'auth_db'
        
        if model == Account:
            return 'auth_db'

        return None

    def allow_relation(self, obj1, obj2, **hints):
        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):
        if app_label in self.route_app_labels:
            return db == 'auth_db'
        
        return None
    
    
class AcmeAppRouter:
    route_app_labels = ['acmeapp']

    def db_for_read(self, model, **hints):
        if model._meta.app_label in self.route_app_labels:
            return 'acmeapp_db'

        return None

    def db_for_write(self, model, **hints):
        if model._meta.app_label in self.route_app_labels:
            return 'acmeapp_db'

        return None

    def allow_relation(self, obj1, obj2, **hints):
        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):
        if app_label in self.route_app_labels:
            return db == 'acmeapp_db'
        return None

Создание и применение миграций

После создания вышеуказанного кода, я создаю миграции и применяю их к каждой базе данных.

py manage.py makemigrations
py manage.py migrate --database=acmeapp_db
py manage.py migrate --database=auth_db

/acmeapp/migrations/0001_initial.py

# Generated by Django 4.0.4 on 2022-08-11 07:50

from django.db import migrations, models


class Migration(migrations.Migration):

    initial = True

    dependencies = [
    ]

    operations = [
        migrations.CreateModel(
            name='Account',
            fields=[
                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('password', models.CharField(max_length=128, verbose_name='password')),
                ('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')),
                ('username', models.CharField(max_length=40, unique=True)),
            ],
            options={
                'db_table': 'auth_user',
            },
        ),
        migrations.CreateModel(
            name='Foo',
            fields=[
                ('mission_id', models.BigAutoField(primary_key=True, serialize=False)),
                ('name', models.TextField()),
                ('retired', models.BooleanField(default=False)),
            ],
            options={
                'db_table': 'foos',
            },
        ),
    ]

У которой есть две модели, включая Account.

В результате две базы данных созданы и имеют таблицы следующего вида:

acmeapp_db.sqlite

acmeapp_db.sqlite

auth_db.sqlite

auth_db.sqlite

Вернуться на верх