2015-10-29 9 views
8

Mamy aplikację Django, która łączy się z wieloma instancjami bazy danych MS SQL. Istnieje router.py dla każdej aplikacji, która obsługuje routing procesów do każdej bazy danych.Django z wieloma bazami danych i routerami specyficznymi dla aplikacji, nie może dodawać użytkowników do MSSQL

To jest moja pierwsza konfiguracja dostępu do wielu baz danych.

Django wbudowane aplikacje są kierowane do domyślnej bazy danych za pośrednictwem tego 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 

Jesteśmy przy użyciu uwierzytelniania LDAP i Django wbudowanego w uwierzytelniania. Chodzi o to, że użytkownicy intranetu mogą uwierzytelniać się na naszym serwerze AD. Użytkownicy zewnętrzni mogą się zarejestrować i zostaną uwierzytelnieni za pomocą uwierzytelniania Django.

Kiedy mam domyślny zestaw do bazy danych:

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

prac LDAP, ale nie mogę dodać użytkownika do uwierzytelniania Django. Administrator wyświetla komunikat "Sukces", ale użytkownik nie jest dodawany do bazy danych.

Po przełączeniu domyślnej bazy danych z powrotem na SQLLite, jestem w stanie uwierzytelnić się w AD i dodać użytkowników Django.

Nie sądzę, że jest to problem związany z plikiem routers.py. Obawiam się, że może to być problem z silnikiem "sql_server.pyodbc".

EDIT: Na życzenie, oto ustawienia bazy danych:

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': '', 
    }, 
} 

UWAGA: myślę, że może to mieć związek z okazji Django zapisuje nowych użytkowników. Zamierzam tam zajrzeć. Mogę użyć komendy createsuperuser, aby dodać kolejnych superużytkowników, gdy oba serwery uwierzytelniające są na miejscu. Potwierdzone, mogę tworzyć zwykłych użytkowników za pośrednictwem powłoki, ale nie przez administratora.

Notatka uzupełniająca: Nadal nie pojawił się problem z administratorem, ale stwierdziłem, że mogę dodawać użytkowników za pomocą formularza. Myślę, że problem musi być błędem w administratorze.

Edit:

Per użytkownika @ AndrewSmiley życzenie:

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 

UPDATE:

Per @ user1797792 sugestie, stworzyłem własny UserCreationForm aby ustawić wartość date_joined, ale nadal nie możemy dodawać użytkowników za pośrednictwem Administratora Django.

Istotne forms.py & wpisy admin.py są poniżej:

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) 
+0

Nie jestem pewien, czy to pomoże, ale czy możesz opublikować całe ustawienia baz danych? –

+0

@TitusP, dodałem całą konfigurację bazy danych. Jestem z tobą, nie jestem pewien, czy to pomoże. –

+0

Masz tę samą 'app_list' zdefiniowaną wiele razy, dlaczego nie zdefiniować jej w klasie? Masz kod administratora lub używasz domyślnego administratora Django? – Uri

Odpowiedz

0

Po wykonaniu wszystkich sugestii, które zostały przesłane za pośrednictwem komentarzy i odpowiedzi. Zdaliśmy sobie sprawę, że problemem jest nieudokumentowany błąd w bibliotece django-pyodbc-azure.

Po uruchomieniu bazy danych PostgreSQL i połączeniu naszej aplikacji Django nie mogliśmy odtworzyć tego błędu. Użyliśmy także sterowników FreeTDS/ODBC, aby rozmawiać z bazą danych MSSQL i nie mogliśmy jej odtworzyć.

0

myślę, że istnieje problem z pustych pól, a błąd w UserCreationForm. Nie mogę powtórzyć tego problemu, ponieważ nie mam serwera MSSQL.

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

Funkcja ta jest używana przez polecenie zarządzania. Generuje ona właściwość timezone.now() dla właściwości date_joined, podczas gdy formularz na panelu administracyjnym po prostu używa funkcji save() na samym obiekcie, co nie powoduje tego.

date_joined wydaje się pozostawać NULL, jeśli utworzysz użytkownika w panelu administracyjnym. Czy możesz sprawdzić, czy ta kolumna ma domyślną wartość w bazie danych MSSQL? I jest NIESAMOWITE. Jeśli nie, a nie jest zerowy. Wtedy ich kłamstwo jest twoim problemem.

Następnie należy zmodyfikować UserCreationForm. Here is a StackOverflow entry, który pokazuje, jak to zrobić.

+0

Masz rację. w MSSQL data_joined nie jest zerowa i nie ma wartości domyślnej. Dokona edycji UserCreationForm i opublikuje aktualizację. –

Powiązane problemy