Django,BigIntegerField和django.contrib.auth.user.id

时间:2010-01-07 19:38:06

标签: django biginteger django-contrib

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

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

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

2 个答案:

答案 0 :(得分: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模型中。

然后在每个需要的模型中添加并添加一个foriegnkey。 不要删除原始FK,否则链接将丢失。添加新密钥后,请执行另一个模式迁移。

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

然后可以安全地将旧FK删除到用户模型。

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

如果数据库中没有任何数据,那么您只需实现上面的类并将其放入当前模型中。

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

由于您需要一些“{1}}替代品”,因此您还需要两个步骤: 首先,我们需要创建一个自定义身份验证后端,这可以确保所有身份验证请求都转到您的新模型,并User返回request.user而不是BigUser。只需将此片段剪切并粘贴到与settings.py相同的目录中名为auth_backend.py的文件中:

User

然后在您的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

最后一段代码来自另一个描述用户模型子类的website

现在,您需要做的就是“插入”代码的其余部分,即将所有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

更新User的任何引用

答案 1 :(得分:0)

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

对我来说似乎是最好的方式。

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