Search code examples
djangodjango-admin

Django: Add user to group via Django Admin


How can I add users to a group in Django admin interface of "Change Group"?

I have seen dirty hacks to get this working for older django version.

How to solve this with Django 1.10?

Emphasize: I want this on the page "Change Group", not on "Change User".

I would like to have this in django-admin-style: No coding, just doing some configuration. Maybe like this:

class GroupAdmin(admin.ModelAdmin):
    show_reverse_many_to_many = ('user',)

Solution

  • You need to write some code. Note that the Django admin site is normal Django views and forms!

    First create a ModelForm:

    from django import forms
    from django.contrib import admin
    from django.contrib.auth import get_user_model
    from django.contrib.admin.widgets import FilteredSelectMultiple    
    from django.contrib.auth.models import Group
    
    
    User = get_user_model()
    
    
    # Create ModelForm based on the Group model.
    class GroupAdminForm(forms.ModelForm):
        class Meta:
            model = Group
            exclude = []
    
        # Add the users field.
        users = forms.ModelMultipleChoiceField(
             queryset=User.objects.all(), 
             required=False,
             # Use the pretty 'filter_horizontal widget'.
             widget=FilteredSelectMultiple('users', False)
        )
    
        def __init__(self, *args, **kwargs):
            # Do the normal form initialisation.
            super(GroupAdminForm, self).__init__(*args, **kwargs)
            # If it is an existing group (saved objects have a pk).
            if self.instance.pk:
                # Populate the users field with the current Group users.
                self.fields['users'].initial = self.instance.user_set.all()
    
        def save_m2m(self):
            # Add the users to the Group.
            self.instance.user_set.set(self.cleaned_data['users'])
    
        def save(self, *args, **kwargs):
            # Default save
            instance = super(GroupAdminForm, self).save()
            # Save many-to-many data
            self.save_m2m()
            return instance
    

    We added a custom Group ModelForm. The second step is to unregister the original Group admin and register a new Group admin that displays our ModelForm:

    # Unregister the original Group admin.
    admin.site.unregister(Group)
    
    # Create a new Group admin.
    class GroupAdmin(admin.ModelAdmin):
        # Use our custom form.
        form = GroupAdminForm
        # Filter permissions horizontal as well.
        filter_horizontal = ['permissions']
    
    # Register the new Group ModelAdmin.
    admin.site.register(Group, GroupAdmin)
    

    Screenshot Django custom form and filter_horizontal in Group admin