Django Admin Form for Many to many relationship

前端 未结 4 1199
无人共我
无人共我 2020-12-24 08:15

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

相关标签:
4条回答
  • 2020-12-24 08:29

    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)
    
    0 讨论(0)
  • 2020-12-24 08:30

    I think what you're looking for is InlineModelAdmin.

    0 讨论(0)
  • 2020-12-24 08:38

    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.

    0 讨论(0)
  • 2020-12-24 08:41

    For people who still bump into this, it might be worth checking ​https://github.com/kux/django-admin-extend

    It provides a mechanism for injecting bidirectional many-to-many fields in ModelAdmins that have already been defined by other apps.

    0 讨论(0)
提交回复
热议问题