2014-12-14 2 views
1

기존 데이터베이스에서 Django 프로젝트를 빌드 중입니다. 데이터베이스가 다른 시스템에서 사용되고 있으므로 해당 스키마를 변경할 수 없습니다. 현재 데이터베이스 테이블 AbstractBaseUser.last_login 같은 역할을 last_login_date 열이있는 동안Django 사용자 정의 필드가 AbstractBaseUser와 충돌합니다.

class Users(AbstractBaseUser): 
    id_user = models.IntegerField(primary_key=True) 
    role = models.IntegerField() 
    username = models.CharField(max_length=50, unique=True) 
    last_login_date = models.DateTimeField() 

AbstractBaseUser이 last_login라는 이름의 열을 필요 : 이것은 내 현재 사용자 정의 사용자 모델입니다. 지금은 Users.last_login에 해당 열을 사용할 필요가 장고가 부모의 필드를 무시 허용하지 않기 때문에

... 
    last_login = models.DateTimeField(_('last login'), default=timezone.now, column_name='last_login_date') 
    ... 

그러나 장고 django.core.exceptions.FieldError: Local field 'last_login' in class 'Users' clashes with field of similar name from base class 'AbstractBaseUser'를 던질 것입니다.

필드를 설정하는 방법은 무엇입니까?

답변

1

나는이 작업을 수행 할 수있는 좋은 방법을 알아낼 수 없습니다, 그래서이 오히려 불만족 (그러나 가능한) 솔루션 해킹 당신에게 줄 것이다 :을 활용,

  1. 보다는 AbstractBaseUser에서 상속을 Django의 오픈 소스 다큐 멘 테이션에 대한 자세한 내용은 AbstractBaseUser 코드 (< ...> lib/python3.4/site-packages/django/contrib/auth/models.py)에 복사하고 column_name='last_login_date' last_login 필드에. 합니다 (AbstractBaseUser 클래스는 또한 here (버전 1.7))

  2. 편집 < ...> lib 디렉토리/python3.4/사이트 패키지/장고 /있는 contrib/인증/models.py 직접 (비 이식 가능한 코드의 결과 이미 나는 더 강력한 방법으로 같은 작업을 달성하는 또 다른 방법으로 기여하고자하는 질문을 만족 대답이 있지만 그)도 그것을 해킹하지 않고 다른 장고 설치에

+0

, 당신은 그들이 열 이름 오버라이드 (override) 할 수 있도록 할 수 있는지 장고 프로젝트 버그 보고서를 제출 할 수 있습니다 : 귀하의 경우에는 다음과 같은 할 수 있었다 레거시 데이터베이스를 준수하기 위해 AbstractBaseUser 클래스에 있습니다. – BingsF

+0

감사합니다. ATM 다른 답변을 기다리는 동안 첫 제안을 사용합니다. – pram

2

작동하지 않습니다.

Django AbstractBaseUser는 Django User Class를 대체하는 데 사용해야하는 기본 클래스입니다. 이러한 클래스는 모델을 상속합니다. Model with 모델은 실제로 모델을 만듭니다.

이 클래스는 생성 프로세스를 변경하기 위해 파이썬 데이터 모델의 메타 클래스를 이용합니다.

그게 바로 우리가해야 할 일입니다. Python Data Model에서 읽을 수 있듯이 메타 클래스 특수 속성을 사용하면 생성 프로세스를 변경할 수 있습니다. 다른 누구도 더 나은 해결책을 찾을 수없는 경우

def myoverridenmeta(name, bases, adict): 
    newClass = type(name, bases, adict) 
    for field in newClass._meta.fields: 
     if field.attname == 'last_login': 
      field.column = 'last_login_date' 
      field.db_column = 'last_login_date' 
    return newClass 

class Users(AbstractBaseUser): 
    id_user = models.IntegerField(primary_key=True) 
    role = models.IntegerField() 
    username = models.CharField(max_length=50, unique=True) 

    __metaclass__ = myoverridenmeta