4

我正在运行一个 Django 1.4.2 项目。我有一个 User(models.Model) 类的数据库,现在想更改它,以便我使用来自 django.contrib.auth.models 的内置模型 User。我可以简单地使用我现有的代码并简单地使我自己的自定义用户模型成为 Django 内置的子类吗?这是现在的模型。

class User(models.Model):
    u_id = models.AutoField(primary_key=True)
    #password = models.CharField(max_length=765)
    old_password = models.CharField(max_length=765, null=True, blank=True)
    birthday = models.DateField(null=True, blank=True)
    school_year = models.CharField(max_length=765, blank=True)
    gender = models.CharField(max_length=18, blank=True)
    #email = models.CharField(max_length=765, blank=True)
    profile_pic = models.CharField(max_length=765, blank=True)
    is_cloudinary_pic = models.BooleanField(default=False)
    fb_id = models.CharField(max_length=765, blank=True)
    phone_num = models.CharField(max_length=765, blank=True)
    name = models.CharField(max_length=765, blank=True)
    confirmcode = models.CharField(max_length=765, blank=True)
    status = models.CharField(max_length=765, blank=True)
    netid = models.CharField(max_length=765, blank=True)
    favorites = models.ManyToManyField('listings.Listing', blank=True, related_name='favorites')
    stripe = models.CharField(max_length=765, blank=True)
    rating = models.IntegerField(null=True, blank=True)
    preferences = models.CharField(max_length=765, blank=True)
    b_notification = models.CharField(max_length=765, blank=True)
    l_notification = models.CharField(max_length=765, blank=True)
    address = models.CharField(max_length=765, blank=True)
    city = models.CharField(max_length=765, blank=True)
    state = models.CharField(max_length=6, blank=True)
    zip = models.CharField(max_length=15, blank=True)
    emailprefs = models.CharField(max_length=30, blank=True)
    exp_month = models.CharField(max_length=6, blank=True)
    exp_year = models.CharField(max_length=12, blank=True)
    last4 = models.CharField(max_length=12, blank=True)
    c_type = models.CharField(max_length=765, blank=True)
    user_type = models.CharField(max_length=10, blank=True)
    contract = models.ForeignKey('contracts.Contract', null=True,blank=True, default=None, on_delete=models.SET_NULL)
    last_listing_booked = models.ForeignKey('listings.Listing', null=True,blank=True, default=None, on_delete=models.SET_NULL, related_name='last_listing_booked')
    last_locked_on = models.IntegerField(null=True, blank=True)
    waitlist_number = models.IntegerField(null=True, blank=True)
    waitlist_listing = models.ForeignKey('listings.Listing', null=True, blank=True, on_delete=models.SET_NULL, related_name='waitlist_listing')
    uploaded_contract = models.FileField(upload_to=contract_file_name, max_length=765, null=True, blank=True, default=None, storage=FileSystemStorage(location=os.path.join(MEDIA_ROOT, 'contracts')))

当我在使我的模型成为 Django User 模型的子类之后尝试使用 Django South 进行迁移时,我被要求为 user_ptr 设置一个值,该字段我没有成功找到任何信息。

一般来说,以这种方式简单地进行子类化是不安全的吗?我不能丢失我已经拥有的所有用户数据并重新开始。请注意,密码和电子邮件字段被注释掉,因为它们与 Django 的这些字段版本冲突。

4

2 回答 2

4

如果升级到 Django 1.5 是一个选项,您可以简单地使用您自己的 User 模型,只要它提供所有必需的字段。

user_ptr 是一个隐式 OneToOne 模型,它将您的对象与您派生的类相关联。最简单的方法可能是在以下步骤中手动创建迁移:

  1. 添加带有 null=True 的 user_ptr 字段

  2. 遍历所有 User 对象并创建相应的 auth.User 对象。如果您不确定如何执行此操作,可以阅读South 文档中有关数据迁移的部分。

  3. 禁止空 user_ptr 字段

如果您使用的散列方案与 Django 的内置方法不兼容,您可能需要做的另一件事是实现自己的密码散列器。这不是很难做到,并在另一个问题中得到解决。

于 2013-01-11T20:20:44.260 回答
4

如果使用 Django 1.4,您应该创建一个UserProfile模型而不是从django.contrib.auth.models.User. 直接扩展 Django 的 User 类会导致内部 django.auth 机制的各种麻烦。

您可以在http://www.turnkeylinux.org/blog/django-profile阅读有关如何在 django 中实现用户配置文件的更多信息。

Django 1.5 具有可配置的用户模型,如Vinay Pai的另一个答案中所述。

于 2013-01-11T20:37:00.630 回答