Django现在提供了一个BigIntegerField用于django模型(在svn trunk和1.2 alpha-1版本中可用)。
我需要我的django.contrib.auth.user模型将BigIntegerField作为其自动递增主键,而它当前使用自动递增IntegerField作为其主键。此外,无论将contrib.auth.user用作ForeginKey,它都需要是BigIntegerField。
实现这一目标的最佳和最安全的方法是什么?
答案 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手动迁移数据)