0

Django 现在提供了一个 BigIntegerField 用于 django 模型(在 svn trunk 和 1.2 alpha-1 版本中可用)。

我需要我的 django.contrib.auth.user 模型将 BigIntegerField 作为其自动递增的主键,而它目前使用自动递增的 IntegerField 作为其主键。此外,无论哪里 contrib.auth.user 用作 ForeginKey,它也需要是 BigIntegerField。

实现这一目标的最佳和最安全的方法是什么?

4

2 回答 2

5

虽然我不确定为什么你需要一个 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

然后使用 South 的数据迁移功能将你们所有人复制User.objects.all()到新BigUser模型中。

然后在需要的每个模型中检查并添加一个外键。 请勿删除原始 FK,否则您的链接将丢失。添加新密钥后,再进行一次架构迁移。

然后进行另一次数据迁移,将 FK 从旧用户模型复制到新的 BigUser 模型。迁移该数据。

然后将旧的 FK 删除到 User 模型是安全的。

如果您想避免更改其余代码以使用 BigUser 的新字段名称,您可以使用 South rename-field 实用程序(South 无法自动检测字段重命名,因此请务必阅读文档)。

如果您在数据库中没有任何数据,那么您可以简单地实现上面的类并将其放入您当前的模型中。

如果您在编写数据迁移时需要帮助,您必须发布一两个模型。

由于您需要“插入式”替代品,因此User您还需要两个步骤:首先,我们需要创建一个自定义身份验证后端,以确保任何身份验证请求都转到您的新模型并且request.user返回BigUser而不是User. 只需将此片段剪切并粘贴到与 settings.py 位于同一目录中的名为 auth_backend.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'

最后一段代码来自另一个描述用户模型子类化的网站。

现在,在其余代码中“插入”所需要做的就是将所有from django.contrib.auth.models import User. from your-app-name import BigUser as User通过这样做,您将不必更新任何参考UserwithBigUser

于 2010-01-07T20:22:03.697 回答
0

我正在权衡更改 django.contrib.auth.models.user 的代码以包含一个 id 字段作为 BigIntegerField 主键的选项。

在我看来,这是最好的方法。

(我准备通过sql手动迁移数据)

于 2010-01-08T09:32:37.407 回答