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

我们有一个连接到多个MS SQL数据库实例的Django应用程序.每个应用程序都有一个router.py来处理将进程路由到每个数据库.

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

Django内置应用程序通过此router.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的内置身份验证.这个想法是Intranet用户可以对我们的AD服务器进行身份验证.外部用户可以注册,并将通过Django的身份验证进行身份验证.

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

'default': {
    'ENGINE': 'sql_server.pyodbc',
    'NAME': 'Django',
    'USER': '',
    'PASSWORD': '',
    'HOST': 'sqlbeta',
    'PORT': '',
},

LDAP工作正常,但我无法将用户添加到Django的身份验证中.管理员显示“成功”消息,但用户未添加到数据库中.

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

所以,我不认为这是router.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创建常规用户,但不能通过管理员创建.

跟进说明:
仍然没有找到管理员的问题,但我发现我可以通过表单添加用户.我认为问题必定是管理员中的错误.

编辑:

Per @ AndrewSmiley的要求:

Django Admin Add User View

class UserCreationForm(forms.ModelForm):
    """
    A form that creates a user, with no privileges, from the given username and
    password.
    """
    error_messages = {
        'password_mismatch': _("The two password fields didn't match."),
    }
    password1 = forms.CharField(label=_("Password"),
        widget=forms.PasswordInput)
    password2 = forms.CharField(label=_("Password confirmation"),
        widget=forms.PasswordInput,
        help_text=_("Enter the same password as above, for verification."))

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

    def clean_password2(self):
        password1 = self.cleaned_data.get("password1")
        password2 = self.cleaned_data.get("password2")
        if password1 and password2 and password1 != password2:
            raise forms.ValidationError(
                self.error_messages['password_mismatch'],
                code='password_mismatch',
            )
        return password2

    def save(self, commit=True):
        user = super(UserCreationForm, self).save(commit=False)
        user.set_password(self.cleaned_data["password1"])
        if commit:
            user.save()
        return user

更新:

根据@ user1797792建议,我创建了一个自定义UserCreationForm来设置date_joined值,但是我们仍然无法通过Django Admin添加用户.

相关的form.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服务器.

https://github.com/django/django/blob/1.8.6/django/contrib/auth/models.py#L185

管理命令使用此功能.它为date_joined属性生成timezone.now(),而adminpanel中的Form只对对象本身使用save()函数,而不执行此操作.

如果在管理面板中创建用户,则date_joined似乎保留为NULL.你能检查一下这个列在MSSQL数据库中是否有默认值吗?并且是可空的.
如果没有,那就不可空了.然后他们就是你的问题.

然后你应该编辑UserCreationForm. Here is a StackOverflow entry,它告诉你如何做到这一点.

相关文章
相关标签/搜索