Django Admin Form for Many to many relationship
Solution 1
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.
Solution 2
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)
Solution 3
I think what you're looking for is InlineModelAdmin.
![Admin](/assets/logo_square_200-5d0d61d6853298bd2a4fe063103715b4daf2819fc21225efa21dfb93e61952ea.png)
Admin
Updated on July 09, 2022Comments
-
Admin almost 2 years
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. But I do not see Domains when I am viewing Users. How can I achieve this.
-
Carl Meyer about 15 yearsProbably not what the OP was hoping for (a way to use the regular ManyToMany filter selector from either side of the relation), but this is the solution I would use too.
-
Admin about 15 yearsHow do I refer to the relationship table (Domains_User in my case) I do not have an explicit intermediary table. In this case how do I use InlineModelAdmin for ManyToManyRelationship
-
alalonde over 12 yearsThis didn't quite work for me when adding the 'user' (not a
User
in my case). I needed to check forself.instance.id
in the__init__
method, and I needed tosave()
the new object before assigning domains to it. -
Timo about 10 yearsI get the error message "Test2" not defined which seems logic because Test2 is not defined when called. Your solution would be brillant if working though
-
Pentux over 4 yearsThat's why he added the quotes in Test2, if you add the quotes in 'Test2' will work