在现有django cms项目中使用django自定义用户

在现有django cms项目中使用django自定义用户,django,django-cms,django-custom-user,Django,Django Cms,Django Custom User,我有一个现有的django cms版本。3.1.3我希望用中的模型替换默认django用户模型的项目(将电子邮件作为我用户的用户名)。我已将custom\u user应用程序添加到我的INSTALLED\u APPS中,并设置AUTH\u user\u MODEL='custom\u user.EmailUser'。最后,我应用了迁移 在我的自定义模型中,一切似乎都很正常,但是django cms模型引用了auth_user表(globalpage权限,PagePermission,PageUs

我有一个现有的django cms版本。3.1.3我希望用中的模型替换默认django用户模型的项目(将电子邮件作为我用户的用户名)。我已将
custom\u user
应用程序添加到我的
INSTALLED\u APPS
中,并设置
AUTH\u user\u MODEL='custom\u user.EmailUser'
。最后,我应用了迁移

在我的自定义模型中,一切似乎都很正常,但是django cms模型引用了
auth_user
表(
globalpage权限
PagePermission,
PageUser
UserSettings
),它们没有更新为具有新自定义用户表的外键引用

表示,在项目开始时添加自定义用户模型通常是可取的,但在这里,我在项目的中间,非常希望避免删除我的CMS模型(带数据)以使其正常工作。 如果我在一个项目的开始阶段,并且在迁移django cms模型之前添加了自定义用户模型,那么django cms模型是否会实际获得对自定义用户模型表的引用,而不是默认用户模型表的引用

我有没有办法迁移django cms模型,让它们使用新的自定义用户模型而不是默认模型

使现代化 我正在努力实现雅基的建议:

from __future__ import unicode_literals
from django.conf import settings
from django.db import models, migrations
import django.db.models.deletion
from django.utils.translation import ugettext_lazy as _

def up(apps, schema_editor):
    PageUser = apps.get_model("cms", "PageUser")
    db_alias = schema_editor.connection.alias
    for pu in PageUser.objects.all():
        pu['emailuser_ptr_id'] = pu['user_ptr_id']
        pu.save()

def down(apps, schema_editor):
    PageUser = apps.get_model("cms", "PageUser")
    db_alias = schema_editor.connection.alias
    for pu in PageUser.objects.all():
        pu['user_ptr_id'] = pu['emailuser_ptr_id']
        pu.save()

class Migration(migrations.Migration):

    dependencies = [
        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
        (‘myapp’, ‘previous-migration’),
    ]

    operations = [

        migrations.RenameField(
            model_name='PageUser',
            old_name='user_ptr_id',
            new_name='user_ptr_id_old',
        ),

        migrations.AddField(
            model_name='PageUser',
            name='emailuser_ptr_id',
            field=models.ForeignKey(null=True, to=settings.AUTH_USER_MODEL, verbose_name=_('user'), blank=True),
            preserve_default=True,
        ),

        migrations.RunPython(up, down),

        migrations.RemoveField(
            model_name='PageUser',
            name='user_ptr_id_old',
        ),
    ]

它失败,出现
KeyError:('myapp',u'pageuser')
提示它在我的自定义应用程序中查找
pageuser
模型,而不是在cms应用程序中。如何将这些迁移应用到CMS模型?

< P>称,替换Django用户模型在项目生命周期中是不可取的(参见),因为Django在创建它们之后没有提供任何修改关系的方法,要替换自定义用户模型,您可以编写自定义迁移,将django CMS模型中的foreignkey更改为指向,并为新用户模型创建一个新的

比如:

...
migrations.RenameField(
    model_name='globalpagepermission',
    old_name='user',
    new_name='user_old',
),
migrations.AddField(
    model_name='globalpagepermission',
    name='user',
    field=models.ForeignKey(null=True, to=settings.AUTH_USER_MODEL, verbose_name=_('user'), blank=True),
    preserve_default=True,
),
migrations.RunPython(copy_data),
migrations.RemoveField(
    model_name='globalpagepermission',
    name='user_old',
),
...
对任何相关模型/字段重复上述步骤

copy_data
方法将外键的值从
user_old
复制到
user

代码完全未经测试,但总体思路应该可行

或者,您可以编写一个RunSQL迁移来获得相同的结果


具有相同主键的用户也必须为新模型工作,

据说替换Django用户模型在项目生命周期的中间是不可取的(参见),因为Django在创建它们之后没有提供任何修改关系的方法,要替换自定义用户模型,您可以编写自定义迁移,将django CMS模型中的foreignkey更改为指向,并为新用户模型创建一个新的

比如:

...
migrations.RenameField(
    model_name='globalpagepermission',
    old_name='user',
    new_name='user_old',
),
migrations.AddField(
    model_name='globalpagepermission',
    name='user',
    field=models.ForeignKey(null=True, to=settings.AUTH_USER_MODEL, verbose_name=_('user'), blank=True),
    preserve_default=True,
),
migrations.RunPython(copy_data),
migrations.RemoveField(
    model_name='globalpagepermission',
    name='user_old',
),
...
对任何相关模型/字段重复上述步骤

copy_data
方法将外键的值从
user_old
复制到
user

代码完全未经测试,但总体思路应该可行

或者,您可以编写一个RunSQL迁移来获得相同的结果

具有相同主键的用户也必须存在,才能使新模型正常工作。

多亏了我,我才使它正常工作。这就是我所做的:

  • 备份了我的数据库

  • 创建了一个新的应用程序email_用户名以保存我的用户模型(链接中推荐的命名用户)。一个新的应用程序是必要的,因为我的主应用程序(myapp)依赖于django cms,如果我将我的新用户模型放在myapp中,django cms将依赖于我的应用程序-这将创建一个循环引用

    class User(AbstractEmailUser):
        # Needed to add username, first_name and last_name here, because cms.PageUser model depends on these fields
        username = models.CharField(max_length=100, verbose_name=_('username'))
        first_name = models.CharField(max_length=100, verbose_name=_('first_name'))
        last_name = models.CharField(max_length=100, verbose_name=_('last_name'))
    
        class Meta:
            db_table = 'auth_user' # the model will use the existing auth_user table (at first)
    
  • settings.py

  • 删除了myapp的所有迁移,并截断了
    django_迁移
  • 运行
    manage.py makemigrations
    并获得
  • 无法解析[]的基。此can 如果您从具有迁移的应用程序继承模型(例如。 (contrib.auth)在没有迁移的应用程序中;看见 更多

    。。。因此,我从
    settings.py
    中删除了
    cms
    应用程序,再次运行
    makemigrations
    ,现在成功了,然后重新添加并再次运行
    makemigrations

  • 运行了manage.py migrate--false,但得到了
  • 无法解析[ModelState:'djangcms_file.file',ModelState:'djangcms_video.video',ModelState:'djangcms_link.link',ModelState:'djangcms_googlemap.googlemap',ModelState:'djangcms_picture.picture',ModelState:'djangcms_triser.triser']

    。。。因此,我也从
    settings.py
    中删除了这些应用程序,运行了
    migrate--fake
    ,重新添加了这些应用程序,然后再次执行
    migrate--fake

  • 从新的用户模型中删除了
    db_表
    设置,运行
    makemigrations
    ,然后运行
    migrate
    (无假!)
  • 现在一切似乎都井然有序。以前引用标准auth_user表的所有外键现在都引用我的新用户模型的表。由于db_table技巧,现有用户甚至已经被转移。

    多亏了我,我成功地让它工作了。这就是我所做的:

  • 备份了我的数据库

  • 创建了一个新的应用程序email_用户名以保存我的用户模型(链接中推荐的命名用户)。一个新的应用程序是必要的,因为我的主应用程序(myapp)依赖于django cms,如果我将我的新用户模型放在myapp中,django cms将依赖于我的应用程序-这将创建一个循环引用

    class User(AbstractEmailUser):
        # Needed to add username, first_name and last_name here, because cms.PageUser model depends on these fields
        username = models.CharField(max_length=100, verbose_name=_('username'))
        first_name = models.CharField(max_length=100, verbose_name=_('first_name'))
        last_name = models.CharField(max_length=100, verbose_name=_('last_name'))
    
        class Meta:
            db_table = 'auth_user' # the model will use the existing auth_user table (at first)
    
  • settings.py

  • 删除了myapp的所有迁移,并截断了
    django_迁移
  • 运行
    manage.py makemigrations
    并获得
  • 无法解析[]的基。此can 在继承模型时发生