在现有的django-cms项目中使用django-custom-user

时间:2016-01-17 21:55:03

标签: django django-cms django-custom-user

我有一个现有的django-cms ver。 3.1.3项目我希望用django-custom-user中找到的用户模型替换默认的django用户模型(将电子邮件作为我的用户的用户名)。我已将custom_user应用添加到INSTALLED_APPS并设置AUTH_USER_MODEL = 'custom_user.EmailUser'。最后,我应用了迁移。

我的自定义模型中的所有内容似乎都运行良好,但django-cms模型引用了auth_user表(GlobalPagePermissionPagePermission, PageUser和{ {1}})未更新为具有对新自定义用户表的外键引用。

django-cms documentation表示通常建议在项目开始时添加自定义用户模型,但在这里,我是在项目中间,并且非常希望避免删除我的cms模型(带数据)使其有效。

如果我在项目的开头,并且在迁移django-cms模型之前添加了自定义用户模型,那么django-cms模型是否会实际引用自定义用户模型表而不是默认模型表?

我有没有办法为django-cms模型进行迁移,所以他们使用新的自定义用户模型而不是默认用户模型?

更新

我试图实现yakky建议的内容:

UserSettings

它失败,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')模型,而不是在cms应用中。如何将这些迁移应用于cms模型?

2 个答案:

答案 0 :(得分:3)

据说替换Django User模型在项目生命周期中是不可取的(参见https://docs.djangoproject.com/en/1.9/topics/auth/customizing/#substituting-a-custom-user-model),因为Django在创建关系后没有提供任何修改关系的方法,以替换自定义用户模型,您可以编写自定义迁移,更改django CMS模型中的外键,以指向新用户模型并为其创建一个新的。

类似的东西:

...
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迁移以获得相同的结果。

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

答案 1 :(得分:1)

感谢https://code.djangoproject.com/ticket/25313我设法让它发挥作用。这就是我所做的:

  1. 备份我的数据库!

  2. 创建了一个新的应用程序email_username来保存我的用户模型(按照链接中的建议命名为User)。一个新的应用程序是必要的,因为我的主应用程序(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)
    
  3. AUTH_USER_MODEL = ‘email_username.User’

  4. 中设置settings.py
  5. 删除了myapp的所有迁移并截断了django_migrations
  6. manage.py makemigrations并得到
  7.   

    无法解析[]的基础可以   如果您从具有迁移的应用程序继承模型(例如,   contrib.auth)在没有迁移的应用程序中;看到   https://docs.djangoproject.com/en/1.8/topics/migrations/#dependencies   更多

    ...所以我从cms移除了settings.py应用,再次运行了makemigrations,现在已经成功,然后重新添加并再次运行makemigrations

    1. manage.py migrate --fake,但得到了
    2.   

      无法解析[ModelState:'djangocms_file.File',ModelState:'djangocms_video.Video',ModelState:'djangocms_link.Link',ModelState:'djangocms_googlemap.GoogleMap',ModelState:'djangocms_picture.Picture',ModelState: 'djangocms_teaser.Teaser']

      ...所以我也从settings.py删除了这些应用,运行了migrate --fake,重新添加了应用,再次migrate --fake

      1. 从新用户模型中删除了db_table设置,运行makemigrations后跟migrate(不假冒!)
      2. 现在一切似乎都井井有条。之前引用标准auth_user表的所有外键现在都引用了我的新用户模型的表。由于db_table技巧,现有用户甚至已被转移。