2013-03-24 21 views
21

Özel kullanıcı modelimin kullanıcı adı alanı olarak bir e-posta alanı kullanmak istiyorum. Ben Django'nın AbstractUser modelini sınıflara aşağıdaki özel Kullanıcı modelimiz var:Django 1.5'teki kullanıcı adı alanını e-posta olarak kullanma Özel kullanıcı modeli sonuçları FieldError

class CustomUser(AbstractUser): 
    .... 
    email = models.EmailField(max_length=255, unique=True) 

    USERNAME_FIELD = 'email' 

Ama

python manage.py sql myapp

çalıştırdığınızda aşağıdaki hatayı alıyorum:

FieldError: Local field 'email' in class 'CustomUser' clashes with field of similar name from base class 'AbstractUser'

başıma dahil nedeni e-posta alanı ilk etapta unique=True seçeneğini eklemektir. aksi takdirde olsun:

myapp.customuser: The USERNAME_FIELD must be unique. Add unique=True to the field parameters.

Şimdi açıdan bu kadar: https://docs.djangoproject.com/en/1.5/topics/db/models/#field-name-hiding-is-not-permitted
Bunu başarmak nasıl?

cevap

34

Ian akıllı tepki :) Ancak, ben zaten bana bir çözüm "yamalı" ettik

için çok teşekkür ederim. AbstractUser yana

da beni
benim "kendi" AbstractUser oluşturmaya karar için toplamda en gereksiz bir username alanı var.

AbstractBaseUser ve PermissionsMixin alt sınıflarına göre, herhangi bir kod eklemeden Kullanıcı modeli yerleşik yöntemlerinin çoğunu korurum.

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

class CustomUser(AbstractBaseUser, PermissionsMixin): 
    .... 
    email = models.EmailField(max_length=255, unique=True) 
    first_name = ... 
    last_name = ... 
    is_active = ... 
    is_staff = ... 
    .... 

    objects = CustomUserManager() 

    USERNAME_FIELD = 'email' 


class CustomUserManager(BaseUserManager): 
    def create_user(self, email, password=None, **extra_fields): 
      ..... 

    def create_superuser(self, email, password, **extra_fields): 
      ..... 

Bu çözüm Django yerleşik kod (çoğunlukla modelin bazı tekrarı neden vermez:

Ben de hep birlikte username alanında kullanımını ortadan kaldırmak için özel bir Manager oluşturmak için bu fırsatı yararlandı 'first_name', 'last_name' vb. gibi AbstractUser'da bulunan, ancak daha temiz bir Kullanıcı nesnesi ve veritabanı tablosunda bulunan alanlar.

O USERNAME_FIELD ile 1.5 tanıtılan Flexibily aslında tüm mevcut kısıtlar altında esnek Kullanıcı model oluşturmak için kullanılamaz gerçek bir utanç.

DÜZENLEME: Kapsamlı bir resmi dokümanlar mevcut örnek çalıştı vardır: https://docs.djangoproject.com/en/dev/topics/auth/customizing/#a-full-example

+0

sizin create_superuser yöntemi ne içeriyor? – Siecje

+0

O create_user kullanarak ('yerine email' ile) hiçbir' username' alanına sahip bir kullanıcı nesnesi oluşturur: 'u = self.create_user (e-posta, şifre, ** extra_fields)', süper "özel" alanları ('is_staff setleri, is_superuser, ... ') ve daha sonra bu kullanıcıyı kaydeder. – OrPo

+0

'deafault Django'nın personeli uygulanmak üzere bir olması gerekir ya da bunu atlayabilir CustomUserMananger' ve uygulanmasıdır? O zamanlar gördüğüm kadarıyla – andi

7

Sen CustomUserunique=True için email saha özelliğini değiştirmek için düzenleyebileceğiniz (diğer sonra yerine böyle alanı "user_email" falan adlandırma).

böylece gibi özel kullanıcı sınıfın sonuna ekleyin: Biz _unique değil unique değiştiriyoruz

class CustomUser(AbstractUser): 
    ... 
    USERNAME_FIELD = 'email' 
    ... 
CustomUser._meta.get_field_by_name('email')[0]._unique=True 

Not ikincisi basit @property çünkü.

Bu bir saldırıdır ve bunu çözmek için herhangi bir "resmi" yanıtı duymak isterim.

8

gerçek hedef "kullanıcı adı" değerlerini görmezden benzersiz "e-posta" değerler olduğunu ve, o zaman olabilir:

  • "kullanıcı adını" ile doldurun örn.
  • sha256(user.email).hexdigest()[:30] benzersizliği bu şekilde ekleyin: Sadece beklendiği gibi

    CREATE TABLE "myapp_user" (
        ... 
        "email" varchar(75) NOT NULL, 
        UNIQUE ("email") 
    ) 
    

    eser ve oldukça basittir: Bu sonuçlanır

    class User(AbstractUser): 
        class Meta: 
         unique_together = ('email',) 
    

.

+0

Bu konuyla uğraşırken gördüğüm en iyi seçenek buydu. Çok teşekkürler! – Emilcasvi

2

resmi sitesinden örneği kullanın:

https://docs.djangoproject.com/en/1.7/topics/auth/customizing/#a-full-example

Here is an example of an admin-compliant custom user app. This user model uses an email address as the username, and has a required date of birth; it provides no permission checking, beyond a simple admin flag on the user account. This model would be compatible with all the built-in auth forms and views, except for the User creation forms. This example illustrates how most of the components work together, but is not intended to be copied directly into projects for production use.

+0

Dokümanlara dikkat ettiğiniz için teşekkür ederiz! – user1496984

+0

Bu – danigosa

+1

gitmek için yolu sadece USERNAME_FIELD değiştirmek için aslında gerçekten gerekli olan tüm bu var mı? –

İlgili konular