2017-02-10 2 views
1

Django 1.8.16 django-allauth 0.27.0 Verwenden Postgres als Datenbank.django allauth empty Benutzername verursacht doppelten Schlüssel in Postgreß DB

Meine Anwendung verwendet keine Benutzernamen, nur E-Mail-Adressen als Benutzer-ID. So verwende ich folgende Einstellungen:

ACCOUNT_AUTHENTICATION_METHOD = 'email' 
ACCOUNT_USERNAME_REQUIRED = False 
ACCOUNT_EMAIL_REQUIRED = True 
ACCOUNT_UNIQUE_EMAIL = True 
ACCOUNT_EMAIL_VERIFICATION = "mandatory" 
ACCOUNT_USER_MODEL_USERNAME_FIELD = None 
ACCOUNT_USER_MODEL_EMAIL_FIELD = 'email' 

Nun, wenn ein neuer Benutzer registriert, er Adresse seiner E-Mail verwendet. Aber wenn das Anmeldeformular aus, ich diesen Fehler:

IntegrityError at /accounts/signup/ 
duplicate key value violates unique constraint "auth_user_username_key" 
DETAIL: Key (username)=() already exists. 
Request Method: POST 
Request URL: http://swd.localhost:8000/accounts/signup/ 
Django Version: 1.8.16 
Exception Type: IntegrityError 
Exception Value:  
duplicate key value violates unique constraint "auth_user_username_key" 
DETAIL: Key (username)=() already exists. 

Das sagt genau das, was falsch ist: Der leere Benutzername existiert bereits in der auth_user Tabelle das Feld „Benutzername“, und es scheint dies nicht erlaubt ist? Aber Problem ist, dass das Feld Benutzername ist immer leer mit den obigen Einstellungen. Wie können wir das umgehen?

Ich habe das Benutzermodell nicht angepasst.

+0

In der Datenbank ist das Feld 'Benutzername' als 'eindeutig' gekennzeichnet. Also bedeutet das in der Tat, dass es nicht Null für alle Benutzer sein kann. Ich kann diese 'einzigartige' Einschränkung auf DB-Ebene entfernen, aber es sollte einen saubereren Weg geben, dies zu tun? – Davy

+0

Entfernen auf DB-Ebene scheint nicht einfach und ist nicht das Richtige zu tun. Wie können wir das umgehen? Danke für Ihre Hilfe. – Davy

Antwort

1

gelöst durch ein allauth Konto Adapter zu schreiben, die das user.username Feld mit der E-Mail-Adresse füllt:

from allauth.account.adapter import DefaultAccountAdapter 

class AccountAdapter(DefaultAccountAdapter): 
    def save_user(self, request, user, form, commit=False): 
     data = form.cleaned_data 
     user.username = data['email'] # username not in use 
     user.email = data['email'] 
     if 'password1' in data: 
      user.set_password(data['password1']) 
     else: 
      user.set_unusable_password() 

     user.save() 
     return user 

Haben Sie nicht die Einstellungen ändern.

Inspiriert von: How could one disable new account creation with django-allauth, but still allow existing users to sign in?

+0

Nur neugierig, wenn Sie überhaupt versucht haben, die Einstellungen überhaupt zu ändern, wie bei der anderen Antwort? Immerhin ist @pennersr der Hauptautor von django-alllauth, also hat sein Vorschlag wahrscheinlich Sinn gemacht ... – ZG101

+0

Wie oben erwähnt: Da der Benutzername in der Datenbank als eindeutig markiert ist, hat das Ändern von ACCOUNT_USER_MODEL_USERNAME_FIELD auf None nicht für mich gelöst (" Zweitschlüssel"). Vielleicht haben andere Einstellungen einen Einfluss? – Davy

+0

Ich verstehe. Diese Einstellung wird nur für benutzerdefinierte Benutzermodelle geändert (z. B. wenn Sie stattdessen den Benutzernamen 'personname' aufrufen), die Sie nicht haben. Daher ist das eigentliche Problem, dass Sie keine leeren Benutzernamen für das Standard-Benutzermodell verwenden können (sonst erhalten Sie Duplikate, wenn jeder Benutzername '' (leer) ist). Ihre Lösung funktioniert, weil sie verhindert, dass der Benutzername leer ist. Wenn Sie jedoch nicht sicherstellen, dass die E-Mail-Adresse eindeutig ist, schlägt sie fehl, wenn jemand dieselbe E-Mail zweimal verwendet (weil ihre Benutzernamen doppelt vorhanden sind). – ZG101

2

Auf diese Weise ...

ACCOUNT_USER_MODEL_USERNAME_FIELD = None

... Sie sagen allauth, dass Ihr Benutzermodell keine username Feld hat. In Ihrem Fall ist das eindeutig falsch, da Sie in dieser Spalte einen Einschränkungsfehler erhalten. Setzen Sie es einfach auf "username" anstelle von None, damit allauth das Feld korrekt auffüllt.

+0

In der Tat, wenn ich es auf "keine" setzen, sollte ich dieses Feld aus dem Benutzermodell entfernen? Oder zumindest die "eindeutige" Einschränkung für dieses Feld entfernen.Tatsache ist, dass es standardmäßig vorhanden ist, also ist die Verwendung des Felds username nicht so einfach, da ACCOUNT_USER_MODEL_USERNAME_FIELD nur auf None gesetzt wird, wie an vielen Stellen erklärt, einschließlich dieser eher offiziellen Referenz: http://django-allauth.readthedocs.io/en/latest /advanced.html – Davy