I believe what you want is a filter_horizontal widget used in the Admin template. This should help: Django Admin ManyToManyField

Answer from souldeux on Stack Overflow
🌐
Medium
josephyoungquist.medium.com › howto-django-admin-manytomanyfield-ux-in-both-directions-b700b4720a2e
Better UX Django Admin on M2M. I recently inherited a 10+ year old… | by Joseph Youngquist | Medium
May 20, 2023 - Today, we’re here to implement ... who Administrate the above mentioned app. For those looking to get to the code and bypass the journey, scroll down to the “The Fixed Code”. For the fellow traveler who enjoys the journey, read on my friend. Read on. I’ve boiled this down to use Django’s documented “Pizza” example that demonstrates how to use and setup ManyToManyField ...
Discussions

Django Admin Form for Many to many relationship - Stack Overflow
I have a many to many relationship between 2 tables Users an Domains. I have defined this relationship in the Domains class. So in the admin interface I see the Users when I am viewing Domains. Bu... More on stackoverflow.com
🌐 stackoverflow.com
Django Admin ManyToManyField - Stack Overflow
I'm a bit confused about the previous text, as you have class ProfileADmin(UserAdmin), which looks like admin.py, but then in the next line you define a model field. If you paste your full code, we can help you get it working easier. ... Find the answer to your question by asking. More on stackoverflow.com
🌐 stackoverflow.com
November 10, 2011
A Better Django Admin ManyToMany Field Widget
Bring the best of human thought and AI automation together at your work. Explore Stack Internal ... I find the the Django Admin's default models.ManyToManyField widget to be cumbersome to use. It's the HTML select element and if you have a lot of Objects of the "other" model then it's quite ... More on stackoverflow.com
🌐 stackoverflow.com
Read fields from ManyToMany field via InlineModel
I can view users’ books and the user of the books in the admin panel. I want to view the name and isbn number of the book in tabular inline but I cannot access them User and Uook are connected by a many to many relation… More on forum.djangoproject.com
🌐 forum.djangoproject.com
5
0
January 10, 2024
🌐
Django Forum
forum.djangoproject.com › using django › the admin
ManyToManyField - The Admin - Django Forum
August 29, 2022 - Hey everyone, I am doing a ToDo app which should look like this: I have a submit field to add a new list which was never working, not this afternoon and now. The list is below. It is still ‘a work in progress’. Inside of the list I want to have several items linked to the title.
🌐
Agiliq
books.agiliq.com › projects › django-admin-cookbook › en › latest › many_to_many.html
4. How to show many to many or reverse FK fields on listview page? — Django Admin Cookbook 2.0 documentation
@admin.register(Hero) class HeroAdmin(admin.ModelAdmin, ExportCsvMixin): ... def children_display(self, obj): return ", ".join([ child.name for child in obj.children.all() ]) children_display.short_description = "Children" ... You can use the same method for M2M relations as well. You should also read How to get Django ...
🌐
Django
code.djangoproject.com › ticket › 12203
#12203 (ManyToManyField with through model can't be used in admin) – Django
M2M docs say "For example, if an owner can own multiple cars and cars can belong to multiple owners – a many to many relationship – you could filter the Car foreign key field to only display the cars owned by the User" ​https://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.formfield_for_manytomany
🌐
GitHub
gist.github.com › Grokzen › a64321dd69339c42a184
Symmetrical ManyToMany Filter Horizontal in Django Admin · GitHub
from django.utils.translation import gettext_lazy as _ ... Thanks, this really helped me! Note that if you define fields on ToppingAdmin and not on ToppingAdminForm then you can leave out the class Meta. ... Looking for a admin filter on the reverse side. So I am on the half way (of impossible?).
🌐
Medium
medium.com › @aswinshenoy › django-admin-setting-up-many-to-many-relationships-with-intermediate-models-782895cb48b2
Django Models: Setting up Many-to-Many Relationships through Intermediate Models | by Ashwin Shenoy | Medium
November 15, 2018 - Achieve is a movie-artist, bidirectional, many-to-many relationship (with intermediate model). Ability to ‘select’ artists in movie page, and ‘select’ movies in artist page. Specify role/character name of the artist in the movie (using a intermediate model). class role_inline(admin.TabularInline): model = role extra = 1
Find elsewhere
Top answer
1 of 4
16

I know that this is an older thread, but this was the first result that came up on google and I thought a better answer was necessary.

Via this django bug report I found the best way to have your ManyToManyField show up on both models:

class Test1(models.Model):
    tests2 = models.ManyToManyField('Test2', blank=True)

class Test2(models.Model):
    tests1 = models.ManyToManyField(Test1, through=Test1.tests2.through, blank=True)

I have tested it myself and was very pleased with the results.

2 of 4
12

The only built-in way is via an InlineModelAdmin, but you can use a custom ModelForm with your User ModelAdmin to create field for this purpose. See the code below for simplified setup (assumes users = ManyToManyField(related_name='domains')).

### yourapp/admin.py ###

from django import forms
from django.contrib import admin
from django.contrib.auth.models import User
from django.utils.translation import ugettext_lazy as _
from django.contrib.admin.widgets import FilteredSelectMultiple

from .models import Domain

class DomainAdmin(admin.ModelAdmin):
    filter_horizonal = ('users',)

class UserAdminForm(forms.ModelForm):
    domains = forms.ModelMultipleChoiceField(
        queryset=Domain.objects.all(), 
        required=False,
        widget=FilteredSelectMultiple(
            verbose_name=_('Domains'),
            is_stacked=False
        )
    )

    class Meta:
        model = User

    def __init__(self, *args, **kwargs):
        super(UserAdminForm, self).__init__(*args, **kwargs)

        if self.instance:
          self.fields['domains'].initial = self.instance.domains.all()

    def save(self, commit=True):
        user = super(UserAdminForm, self).save(commit=False)

        user.domains = self.cleaned_data['domains']

        if commit:
            user.save()
            user.save_m2m()

        return user

class UserAdmin(admin.ModelAdmin):
    form = UserAdminForm

admin.site.register(Domain, DomainAdmin)
admin.site.unregister(User)
admin.site.register(User, UserAdmin)
🌐
Django
code.djangoproject.com › ticket › 897
#897 (Bi-Directional ManyToMany in Admin) – Django
I was very surprised to see this 3-digit ticket, because I saw the functionality mostly work on Django 2.2 to 4.2. The issue described in comment:48 was in fact introduced in 5.1, while fixing #35056: A check rejecting M2M fields with through models on the admin was crashing on reverse relations, and the fix for it rejects all reverse M2M fields from the admin, whether they do or don't have a through relation.
🌐
GitHub
gist.github.com › jdklub › 9261959
Edit a many-to-many relationship (ManyToManyField) on the Django Admin change list page. · GitHub
""" base https://gist.github.com/jdklub/9261959 https://gist.github.com/quxf2012/b1827d2bf02322c2779e8309ba089163 usage: @admin.register(XxxModel) class XxxModelAdmin(ModelMultipleListEdit, admin.ModelAdmin): m_list_editable = {'mtomfield': MtomModel.objects.all()} # ModelMultipleListEdit use """ from django import forms from django.forms.utils import flatatt from django.utils.safestring import mark_safe __all__ = ['ModelMultipleListEdit'] class StyleableCheckboxSelectMultiple(forms.CheckboxSelectMultiple): def __init__(self, attrs=None, ul_attrs=None): self.ul_attrs = ul_attrs super().__init_
Top answer
1 of 1
83

Hmm, I don't think you want inlines here.

You want to be using the Django admin's filter_horizontal:

https://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.filter_horizontal

class ProfileAdmin(UserAdmin)
    filter_horizontal = ('opetest',)

That will give you the widget that you're describing, used to add/remove Groups on the User Change page.


Ok, based on your edits, updated answer - basically, what we have is a UserProfile, linked to each user.

The UserProfile contains a m2m relationship to opetest - which we show in the admin with a filter_horizontal. End result is something like this:

models.py

from django.db import models
from django.contrib.auth.models import User

class opetest(models.Model):
    name = models.CharField(max_length=200)
    author = models.ForeignKey(User, related_name='author')
    description = models.TextField(u'Test description', help_text = u'Some words about quiz')
    pub_date = models.DateTimeField('date published', blank=False)
    #vacancies = models.ManyToManyField(Vacancy, blank=True)
    students = models.ManyToManyField(User, blank=True, related_name='opetests') #This field I want to edit on "User change page"
    estimate = models.IntegerField(default = 0, help_text = u'Estimate time in hours. \'0\' - unlimited')

class UserProfile(models.Model):
    user = models.OneToOneField(User, unique=True)
    ope = models.ManyToManyField(opetest)
    test_flag = models.BooleanField()

admin.py

from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from django.contrib.auth.models import User
from secondapp.models import UserProfile, opetest

admin.site.unregister(User)

class opetestAdmin(admin.ModelAdmin):
    pass

class UserProfileInline(admin.StackedInline):
    model = UserProfile
    filter_horizontal = ('ope',)

class CustomUserAdmin(UserAdmin):
    #filter_horizontal = ('user_permissions', 'groups', 'ope')
    save_on_top = True
    list_display = ('username', 'email', 'first_name', 'last_name', 'is_staff', 'last_login')
    inlines = [UserProfileInline]

admin.site.register(User, CustomUserAdmin)
admin.site.register(opetest, opetestAdmin)

Let me know if you have any questions, or need anything further.

🌐
TimOnWeb
timonweb.com › tim kamanin — a django/wagtail developer › django › many-to-many field, save() method and the django admin caveat
Many-to-many field, save() method and the Django admin caveat ⚡ | TimOnWeb
July 12, 2021 - So if you want to add many to many relationships on model save (for example, you want to add categories) in model save method like these: def save(self, *args, **kwargs): category = Category.objects.get(pk=1) self.categories.add(category) It won't work if you save model via admin, so to fix that you need to override save_related method on model admin form:
🌐
Medium
medium.com › django-unleashed › mastering-manytomanyfield-in-django-a-comprehensive-guide-to-effective-relationship-management-988156073f5d
Mastering ManyToManyField in Django: A Comprehensive Guide to Effective Relationship Management | by Mehedi Khan | Django Unleashed | Medium
February 15, 2025 - Mastering the ManyToManyField in Django involves a deep understanding of how to define, manage, and optimize many-to-many relationships between models. This comprehensive guide will cover various aspects, including creating relationships, working with the Django admin, handling forms, querying relationships, customizing fields, and optimizing queries.
🌐
Django Forum
forum.djangoproject.com › using django › the admin
Read fields from ManyToMany field via InlineModel - The Admin - Django Forum
January 10, 2024 - I can view users’ books and the user of the books in the admin panel. I want to view the name and isbn number of the book in tabular inline but I cannot access them User and Uook are connected by a many to many relationship class UserInline(admin.TabularInline): model = Book.author.through class BookInline(admin.TabularInline): model = User.book.through @admin.register(User) class UserAdmin(UserAdmin): list_filter = [] list_display = ['username', 'email'] list_per_page = ...
🌐
Reddit
reddit.com › r/django › manytomany relation with through model is blowing up queries in django admin
r/django on Reddit: ManyToMany relation with through model is blowing up queries in Django Admin
February 18, 2021 -

I spent several hours yesterday trying to get the prefetch_related set up correctly, but opening up an item in the Django Admin is taking approximately 10-20 seconds, and according to the debug toolbar, running around 550 queries

I have the following relation of models:

class Card(models.Model):
    id = models.UUIDField(primary_key=True)
    name = models.CharField(max_length=200)

    def __str__(self):
        return self.name


class MagicSet(models.Model):
    id = models.UUIDField(primary_key=True)
    name = models.CharField(max_length=100)
    printings = models.ManyToManyField(Card, through='Printing')

    def __str__(self):
        return self.name


class Printing(models.Model):
    magic_set = models.ForeignKey(MagicSet, on_delete=models.CASCADE)
    card = models.ForeignKey(Card, related_name='printings', on_delete=models.CASCADE)

and my admin.py contains the following:

class PrintingInline(admin.TabularInline):
    model = MagicSet.printings.through
    extra = 0


@admin.register(MagicSet)
class MagicSetAdmin(admin.ModelAdmin):
    inlines = [
        PrintingInline,
    ]

    def get_queryset(self, request):
        queryset = super().get_queryset(request)
        queryset = queryset.prefetch_related('printings')
        return queryset

Most of the documentation that I saw about using M2M w/ a through model and the admin seemed to imply that this should just work, can someone tell me what I've done wrong?

Update 2/18: I just wanted to drop an update in case someone came across this later. Unfortunately, I haven't found a good solution to this issue, but everything works just fine in a regular Django view. Since I just intend to use the admin during development, I created a custom view to accomplish what I needed to (which is mostly just inspecting the data), and it works just fine using a prefetch_related query. Sorry if this wasn't more helpful

🌐
Django
docs.djangoproject.com › en › 4.1 › ref › contrib › admin
The Django admin site | Django documentation | Django
January 24, 2023 - As long as the fields appear in list_display, Django doesn’t care how many (or how few) fields are linked. The only requirement is that if you want to use list_display_links in this fashion, you must define list_display. In this example, the first_name and last_name fields will be linked on the change list page: class PersonAdmin(admin.ModelAdmin): list_display = ('first_name', 'last_name', 'birthday') list_display_links = ('first_name', 'last_name')
🌐
GeeksforGeeks
geeksforgeeks.org › python › how-to-show-a-many-to-many-field-with-listdisplay-in-django-admin
How to Show a Many-to-Many Field with "list_display" in Django Admin - GeeksforGeeks
July 31, 2024 - You should now see a list of books with their associated authors displayed in the list view. ... Displaying many-to-many fields in the Django Admin interface using the list_display attribute involves defining a custom method in the model admin class.