How do I extend the Django Group model?

前端 未结 4 1054
Happy的楠姐
Happy的楠姐 2020-12-01 02:12

Is there a way to extend the built-in Django Group object to add additional attributes similar to the way you can extend a user object? With a user object, you can do the fo

4条回答
  •  孤独总比滥情好
    2020-12-01 02:39

    I managed to use migrations with @Semprini aswer.

    So i needed to create a company related field in my groups related field, so in my models i did this:

    if not hasattr(Group, 'company'):
        field = models.ForeignKey(Company, on_delete=models.DO_NOTHING, null=True)
        field.contribute_to_class(Group, 'company')
    
    
    class Group(Group):
    
        class Meta:
            proxy = True
    

    Then i run manage.py makemigrations. This created 2 files. One with dependencies on the other, but the first one belonging to the auth app was created inside my virtual enviroment. The files look like this:

    # Generated by Django 2.2.5 on 2019-10-08 16:00
    
    from django.db import migrations, models
    import django.db.models.deletion
    
    
    class Migration(migrations.Migration):
    
        dependencies = [
            ('myapp', '0013_guestuser_permissions_20190919_1715'),
            ('auth', '0011_update_proxy_permissions'),
        ]
    
        operations = [
            migrations.AddField(
                model_name='group',
                name='company',
                field=models.ForeignKey(
                    null=True, on_delete=django.db.models.deletion.DO_NOTHING, to='myapp.Company'),
            ),
        ]
    

    The second one created in myapp migrations folder look like this:

    # Generated by Django 2.2.5 on 2019-10-08 16:00
    
    import django.contrib.auth.models
    from django.db import migrations
    
    
    class Migration(migrations.Migration):
    
        dependencies = [
            ('auth', '0012_group_company_20191008'),
            ('myapp', '0013_guestuser_permissions_20190919_1715'),
        ]
    
        operations = [
            migrations.CreateModel(
                name='Group',
                fields=[
                ],
                options={
                    'proxy': True,
                    'indexes': [],
                    'constraints': [],
                },
                bases=('auth.group',),
                managers=[
                    ('objects', django.contrib.auth.models.GroupManager()),
                ],
            ),
        ]
    

    So the solution was to move the file created in my virtualenv to myapp migrations folder, before the other one generated with makemigrations, but since the migration is applied to the auth app instead of myapp i have to implement a workaround in the file. So the final file now is:

    # Generated by Django 2.2.5 on 2019-10-08 16:00
    
    from django.db import migrations, models
    import django.db.models.deletion
    
    
    class Migration(migrations.Migration):
    
        dependencies = [
            ('myapp', '0013_guestuser_permissions_20190919_1715'),
            ('auth', '0011_update_proxy_permissions'),
        ]
    
        operations = [
            migrations.AddField(
                model_name='group',
                name='company',
                field=models.ForeignKey(
                    null=True, on_delete=django.db.models.deletion.DO_NOTHING, to='myapp.Company'),
            ),
        ]
    
        def mutate_state(self, project_state, preserve=True):
            """
            This is a workaround that allows to store ``auth``
            migration outside the directory it should be stored.
            """
            app_label = self.app_label
            self.app_label = 'auth'
            state = super(Migration, self).mutate_state(project_state, preserve)
            self.app_label = app_label
            return state
    
        def apply(self, project_state, schema_editor, collect_sql=False):
            """
            Same workaround as described in ``mutate_state`` method.
            """
            app_label = self.app_label
            self.app_label = 'auth'
            state = super(Migration, self).apply(project_state, schema_editor, collect_sql)
            self.app_label = app_label
            return state
    
    

    The mutate an apply methods allow you to migrate to the auth app from myapp migrations.

    In the second file i just change the dependencie to depend on the newly file created:

    # Generated by Django 2.2.5 on 2019-10-08 16:00
    
    import django.contrib.auth.models
    from django.db import migrations
    
    
    class Migration(migrations.Migration):
    
        dependencies = [
            ('myapp', '0014_group_company_20191008'),
            ('myapp', '0013_guestuser_permissions_20190919_1715'),
        ]
    
        operations = [
            migrations.CreateModel(
                name='Group',
                fields=[
                ],
                options={
                    'proxy': True,
                    'indexes': [],
                    'constraints': [],
                },
                bases=('auth.group',),
                managers=[
                    ('objects', django.contrib.auth.models.GroupManager()),
                ],
            ),
        ]
    
    

提交回复
热议问题