60๐
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)
2๐
You have to write code to achieve what you want, since django admin provides the change form, for the model that has the M2M field in it, namely User
, since m2m to Group
is inside that model.
So basically, doing it completely in django admin and nice, you probably need to override several functions and provide your own implementation.
class GroupForm(forms.Form):
blah
users = forms.ModelMultipleChoiceField(
label=_('Users'), required=False, queryset=User.objects.all(),
widget=FilteredSelectMultiple(is_stacked=True, verbose_name=_('Users')),help_text=mark_safe("Help text")
)
class GroupAdmin(BaseAdmin):
form = GroupForm
# you can here define fieldsets to render your form more beautifully
def save_related(self, request, form, formsets, change):
current_group = form.instance
# ....
# Update relations between users and the group here, both are
# accessible with the form instance
def get_changeform_initial_data(self, request):
# If you want to render the form with initial data for the user
# you may optionally override this method as well.
initial = super(GroupAdmin, self).get_changeform_initial_data(request)
initial.update({'users': ...})
return initial
This is the most django-ic way I find to implement what you want! Hope it helps or give you an idea
- How to populate user profile with django-allauth provider information?
- Is there a way to set the id value of new Django objects to start at a certain value?
- RuntimeError: Never call result.get() within a task Celery
- Django template counter in nested loops
0๐
On Change group page you have to override the change group form and add a multiple selectbox with users