Python Django具有多个数据库和特定于应用程序的路由器,无法在MSSQL中添加用户

Python Django具有多个数据库和特定于应用程序的路由器,无法在MSSQL中添加用户,python,sql-server,django,authentication,django-auth-ldap,Python,Sql Server,Django,Authentication,Django Auth Ldap,我们有一个Django应用程序,它连接到多个MS SQL数据库实例。每个应用程序都有一个router.py,用于将进程路由到每个数据库 这是我第一次设置多数据库访问 Django内置应用通过以下路由器路由到默认数据库。py: class DjangoRouter(object): """ A router to control all database operations on models in the auth application. """ def db_for_read(self,

我们有一个Django应用程序,它连接到多个MS SQL数据库实例。每个应用程序都有一个router.py,用于将进程路由到每个数据库

这是我第一次设置多数据库访问

Django内置应用通过以下路由器路由到默认数据库。py:

class DjangoRouter(object):
"""
A router to control all database operations on models in the
auth application.
"""

def db_for_read(self, model, **hints):
    """
    Attempts to read auth models go to auth.
    """
    app_list = ('auth', 'admin', 'contenttypes', 'sessions',)

    if model._meta.app_label in app_list:
        return 'default'
    return None

def db_for_write(self, model, **hints):
    """
    Attempts to write auth models go to auth.
    """
    app_list = ('auth', 'admin', 'contenttypes', 'sessions',)
    if model._meta.app_label in app_list:
        return 'default'
    return None

def allow_relation(self, obj1, obj2, **hints):
    """
    Allow relations if a model in the auth app is involved.
    """
    app_list = ('auth', 'admin', 'contenttypes', 'sessions',)
    if obj1._meta.app_label in app_list and obj2._meta.app_label in app_list:
        return True
    return None

def allow_migrate(self, db, app_label, model=None, **hints):
    """
    Make sure the auth app only appears in the 'auth'
    database.
    """
    app_list = ('auth', 'admin', 'contenttypes', 'sessions',)

    if app_label in app_list:
        return db == 'default'
    return None
我们正在使用LDAP身份验证和Django的内置身份验证。其想法是,内部网用户可以通过我们的AD服务器进行身份验证。外部用户可以注册,并将通过Django的身份验证进行身份验证

当我将默认数据库设置为:

'default': {
    'ENGINE': 'sql_server.pyodbc',
    'NAME': 'Django',
    'USER': '',
    'PASSWORD': '',
    'HOST': 'sqlbeta',
    'PORT': '',
},
LDAP可以工作,但我无法将用户添加到Django的身份验证中。管理员显示一条“成功”消息,但用户未添加到数据库中

如果我将默认数据库切换回SQLLite,我就能够针对AD进行身份验证并添加Django用户

因此,我认为routers.py文件没有问题。我担心这可能是“sql_server.pyodbc”引擎的问题

编辑: 根据请求,以下是数据库设置:

DATABASES = {
    # 'default': {
    #    'ENGINE': 'django.db.backends.sqlite3',
    #    'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    # },
    'default': {
        'ENGINE': 'sql_server.pyodbc',
        'NAME': 'Django',
        'USER': '',
        'PASSWORD': '',
        'HOST': 'sqlbeta',
        'PORT': '',
    },
    'master': {
        'ENGINE': 'sql_server.pyodbc',
        'NAME': 'master',
        'USER': '',
        'PASSWORD': '',
        'HOST': 'sqlbeta',
        'PORT': '',
    },
    'databaseone': {
        'ENGINE': 'sql_server.pyodbc',
        'NAME': 'databaseone',
        'USER': '',
        'PASSWORD': '',
        'HOST': 'sqlbeta',
        'PORT': '',
    },
    'databasetwo': {
        'ENGINE': 'sql_server.pyodbc',
        'NAME': 'databasetwo',
        'USER': '',
        'PASSWORD': '',
        'HOST': 'sqlbeta',
        'PORT': '',
    },
}
注: 我认为这可能与Django保存新用户的方式有关。我要去那里看看。我可以使用createsuperuser命令在两个身份验证后端都就绪时添加更多超级用户。确认,我可以通过shell创建普通用户,但不能通过管理员

后续说明: 仍然没有发现管理员的问题,但我发现我可以通过表单添加用户。我想这个问题一定是管理员的错误

编辑:

根据@AndrewSmiley的请求:

更新:

根据@user1797792建议,我创建了一个自定义UserCreationForm来设置加入日期值,但我们仍然无法通过Django管理员添加用户

相关forms.py和admin.py条目如下:

class CustomUserCreationForm(UserCreationForm):
    now = timezone.now()

    class Meta:
        model = User
        fields = ('username',)

    def save(self, commit=True):
        user = super(CustomUserCreationForm, self).save(commit=False)
        user.date_joined = self.now
        if commit:
            user.save()
        return user

class CustomUserAdmin(UserAdmin):
    add_form = CustomUserCreationForm

admin.site.unregister(User)
admin.site.register(User, CustomUserAdmin)

我认为可空字段存在问题,UserCreationForm中存在错误。我无法复制此问题,因为我没有MSSQL服务器

此功能由管理命令使用。它为
date\u joined
属性生成一个timezone.now(),而adminpanel中的表单只对对象本身使用save()函数,而对象本身不这样做

如果在“管理”面板中创建用户,则加入日期似乎保留为空。能否检查此列在MSSQL数据库中是否有默认值?并且可以为空。 如果它没有,并且它不可为空。那么他们的谎言就是你的问题


然后您应该编辑UserCreationForm。这将向您展示如何做到这一点。

在遵循通过评论和答案提交的所有建议之后。我们意识到问题是
django-pyodbc-azure
库中的一个未记录的bug


在启动PostgreSQL数据库并连接Django应用程序后,我们无法重新创建此错误。我们还使用FreeTDS/ODBC驱动程序与MSSQL数据库进行对话,但无法重新创建它。

我不确定它是否有用,但您能否发布您的整个数据库设置?@TitusP,我已添加了整个数据库配置。我同意你的观点,不确定这是否有帮助。你已经多次定义了相同的
app\u list
,为什么不在课堂上定义它呢?你有管理员代码吗,或者你在使用Django的默认管理员?@Uri,你是对的,我应该在类中定义一次app_列表。那只是我草率的复制/粘贴。我们只是使用默认的管理员。@Uri,我没有在PostgreSQL或MySQL上尝试过。我还没有制作出任何一个副本来测试。我正在使用
django-pyodbc-azure==1.8.3.0
,这取决于
pyodbc==3.0.10
用于
sql\u-server.pyodbc
。您是正确的。在MSSQL中,日期不可为空,并且缺少默认值。将编辑UserCreationForm并发布更新。
class CustomUserCreationForm(UserCreationForm):
    now = timezone.now()

    class Meta:
        model = User
        fields = ('username',)

    def save(self, commit=True):
        user = super(CustomUserCreationForm, self).save(commit=False)
        user.date_joined = self.now
        if commit:
            user.save()
        return user

class CustomUserAdmin(UserAdmin):
    add_form = CustomUserCreationForm

admin.site.unregister(User)
admin.site.register(User, CustomUserAdmin)