Django, BigIntegerField и django.contrib.auth.user.id - PullRequest
0 голосов
/ 07 января 2010

Django теперь предоставляет BigIntegerField для использования в моделях django (доступно в стволе svn, а также версии 1.2 alpha-1).

Мне нужно, чтобы в моей модели django.contrib.auth.user был BigIntegerField в качестве автоинкрементного первичного ключа, тогда как в настоящее время он использует автоинкрементный IntegerField в качестве первичного ключа. Кроме того, там, где contrib.auth.user используется в качестве ForeginKey, также должен быть BigIntegerField.

Какой самый лучший и безопасный способ добиться этого?

Ответы [ 2 ]

5 голосов
/ 07 января 2010

Хотя я не уверен, зачем вам нужен BigIntegerField on User (у вас должно быть много пользователей lotta), его довольно легко реализовать. Для начала вам нужно получить систему миграции базы данных, такую ​​как 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 модели.

Затем пройдите и ДОБАВЬТЕ в каждой модели клавиатуру по необходимости. НЕ удаляйте исходный FK, в противном случае ссылки будут потеряны . После добавления новых ключей выполните другую миграцию схемы.

Затем выполните другую миграцию данных, которая копирует FK со старой модели User в новую модель BigUser. Перенос этих данных.

Тогда можно безопасно удалить старый FK для модели User.

Если вы не хотите изменять оставшуюся часть кода для использования нового имени поля для BigUser, вы можете использовать утилиту переименования полей на юг (Юг не может автоматически определять переименования полей, поэтому обязательно прочитайте документы ).

Если у вас нет данных в базе данных, вы можете просто реализовать класс, описанный выше, и добавить его в свои текущие модели.

Если вам нужна помощь в написании миграции данных, вам придется опубликовать модель или две.

Так как вам нужно что-то, что заменяет User, вам потребуется еще два шага: Сначала нам нужно создать пользовательский бэкэнд аутентификации, это гарантирует, что любые запросы на аутентификацию отправляются в вашу новую модель и что request.user возвращает BigUser, а не 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'

Этот последний раздел кода взят с другого сайта , описывающего подклассы модели User.

Теперь все, что вам нужно сделать для «вставки» в оставшуюся часть кода, это заменить все from django.contrib.auth.models import User на from your-app-name import BigUser as User. При этом вам не придется обновлять ссылки на User на BigUser

0 голосов
/ 08 января 2010

Я оцениваю возможность изменения кода django.contrib.auth.models.user для включения поля id в качестве первичного ключа BigIntegerField.

Мне кажется, это лучший путь.

(я готов перенести данные вручную через sql)

...