2010-01-07 4 views
0

장고는 이제 django 모델 (svn 트렁크 및 1.2 알파 -1 릴리스에서 사용 가능)에서 사용할 BigIntegerField를 제공합니다.Django, BigIntegerField 및 django.contrib.auth.user.id

BigIntegerField를 자동 증가 기본 키로 사용하려면 django.contrib.auth.user 모델이 필요하지만 현재 기본 키로 자동 증가 IntegerField를 사용합니다. 또한, contrib.auth.user가 ForeginKey로 사용될 때마다 BigIntegerField 여야합니다.

이것을 달성하는 가장 좋은 방법은 무엇입니까?

+0

가 [IntegerField] (https://docs.djangoproject.com/es/1.9/ref/models/fields/#integerfield) 29 수 (나는 SQL을 통해 수동으로 데이터를 마이그레이션 할 준비가되어있다) 세계의 %] (https://www.wolframalpha.com/input/?i=2147483647+%2F+world+popoulation+in+2016). [~ 1.5X facebook의 크기] (https://www.wolframalpha.com/input/?i=2147483647:active+facebook+users)에서, 그것은 심각한 데이터베이스입니다! [BigIntegerField] (https://docs.djangoproject.com/es/1.9/ref/models/fields/#bigintegerfield)는 전 세계의 모든 사용자를 추적하려면 [1 인당 행 수십억 행] (https : //www.wolframalpha.com/input/? i = 9223372036854775807 + % 2F + 세계 + 인구 + 2016 년)! 야기? – meshy

답변

4

사용자가 BigIntegerField를 사용해야하는 이유가 확실하지 않지만 구현하기가 쉽습니다. 먼저 South과 같은 데이터베이스 이전 시스템을 가져와야합니다. 이 기능을 사용하여 현재 데이터를 몇 가지 마이그레이션 할 수 있습니다. 데이터베이스에 아무 것도 없다면이 부분을 무시하고 끝으로 건너 뜁니다.

내가 지금처럼 contrib.auth 버전에서 상속 사용자 정의 사용자 클래스를 만들어 시작할 것

:

from django.contrib.auth.models import User, UserManager 
from django.db import models 

class BigUser(User): 
    id = models.BigIntegerField(pk = True) 

    objects = UserManager() 
    #this lets you transperantly use any 
    #query methods that you could on User 

그런 다음 새에 당신 User.objects.all()의 복사본을 만들기 위해 한국의 데이터 마이그레이션 기능을 사용 BigUser 모델입니다.

그런 다음 필요에 따라 각 모델에서 foriegnkey를 추가하고 추가하십시오. 원래 FK를 삭제하지 마십시오. 그렇지 않으면 링크가 없어집니다.. 새 키를 추가 한 후 또 다른 스키마 이주를 수행하십시오.

그런 다음 기존 User 모델의 FK를 새로운 BigUser 모델로 복사하는 또 다른 데이터 마이그레이션을 수행하십시오. 해당 데이터를 마이그레이션하십시오.

그런 다음 이전 FK를 사용자 모델로 삭제해도 안전합니다.

BigUser의 새 field-name을 사용하도록 나머지 코드를 변경하지 않으려면 South rename-field 유틸리티를 사용할 수 있습니다 (South에서는 필드 이름 변경을 감지 할 수 없으므로 docs).

데이터베이스에 데이터가없는 경우 위의 클래스를 구현하여 현재 모델에 드롭하면됩니다.

데이터 마이그레이션을 작성하는 데 도움이 필요하면 모델을 2 개 이상 게시해야합니다.

User의 "드롭 인"대체물이 필요하므로 두 단계가 더 필요합니다. 먼저 사용자 지정 인증 백엔드를 만들어야합니다. 이렇게하면 인증 요청이 새로운 모델이고 request.userBigUser이고 User은 반환하지 않습니다. 그냥 잘라와 같은 디렉토리에 auth_backend.py settings.py로라는 파일에이 코드를 붙여 넣습니다

from django.conf import settings 
from django.contrib.auth.backends import ModelBackend 
from django.core.exceptions import ImproperlyConfigured 
from django.db.models import get_model 

class CustomUserModelBackend(ModelBackend): 
    def authenticate(self, username=None, password=None): 
     try: 
      user = self.user_class.objects.get(username=username) 
      if user.check_password(password): 
       return user 
     except self.user_class.DoesNotExist: 
      return None 

    def get_user(self, user_id): 
     try: 
      return self.user_class.objects.get(pk=user_id) 
     except self.user_class.DoesNotExist: 
      return None 

    @property 
    def user_class(self): 
     if not hasattr(self, '_user_class'): 
      self._user_class = get_model(*settings.CUSTOM_USER_MODEL.split('.', 2)) 
      if not self._user_class: 
       raise ImproperlyConfigured('Could not get custom user model') 
     return self._user_class 

이 그런 다음 settings.py 파일이 백엔드를 추가하고 사용자 정의 사용자 모델을 설정해야합니다 과 같이 ... 설정 : 코드의

AUTHENTICATION_BACKENDS = (
    'auth_backends.CustomUserModelBackend', 
) 
... 

CUSTOM_USER_MODEL = 'your-app-name.BigUser' 

이 마지막 섹션은 사용자 모델을 서브 클래스를 설명하는 또 다른 website에서 온다.

이제 나머지 코드에서 "놓기"를 수행하기 만하면 from django.contrib.auth.models import User을 모두 from your-app-name import BigUser as User으로 바꿉니다. 이렇게함으로써 당신은 늘 내가 BigIntegerField 기본 키와 같은 id 필드를 포함하는 django.contrib.auth.models.user의 코드를 변경하는 옵션을 무게입니다 BigUser

+0

충분히 명확 하긴하지만 투명하게 작동합니까? 나는 인증, 로그인, 로그 아웃, 그룹 등이 모두 예상대로 작동 할 것인가? django.contrib.auth를 계속 사용하려면 어떻게해야합니까? – gbsmith

+0

@gbsmith 더 나은 드롭 인 대체를 허용하는 답변을 업데이트했습니다. 도움이됩니다. – JudoWill

+0

@JudoWill 당신이 제공 한 웹 사이트 링크와 Django 문서들과 함께 당신의 코드를 읽었을 때,이 코드는 훌륭하게 보입니다. 내 애플 리케이션에서 그것을 밖으로 시도하고 난 contrib.auth.group 작동하는 방법을 시도하고 싶습니다 바로 대답으로 표시 마킹 오전 – gbsmith

0

User의 참조를 업데이트해야합니다.

나에게 가장 좋은 방법이라고 생각됩니다.

+0

나만큼 쉽지 않아 생각. Django의 AutoField는 IntegerField이며 BigIntegerField는 아닙니다. primary = True를 지정하면 한 가지 문제 만 해결됩니다. – gbsmith