How to access both directions of ManyToManyField in Django Admin?

前端 未结 1 1652
日久生厌
日久生厌 2021-02-02 01:42

The Django admin filter_horizontal setting gives a nice widget for editing a many-to-many relation. But it\'s a special setting that wants a list of fields, so it\'

相关标签:
1条回答
  • 2021-02-02 02:21

    Here's a (more or less) tidy solution, thanks to http://blog.abiss.gr/mgogoulos/entry/many_to_many_relationships_and and with a fix for a Django bug taken from http://code.djangoproject.com/ticket/5247

    from django.contrib import admin as admin_module
    
    class SiteForm(ModelForm):
        user_profiles = forms.ModelMultipleChoiceField(
            label='Users granted access',
            queryset=UserProfile.objects.all(),
            required=False,
            help_text='Admin users (who can access everything) not listed separately',
            widget=admin_module.widgets.FilteredSelectMultiple('user profiles', False))
    
    class SiteAdmin(admin_module.ModelAdmin):
        fields = ('user_profiles',)
    
        def save_model(self, request, obj, form, change):
            # save without m2m field (can't save them until obj has id)
            super(SiteAdmin, self).save_model(request, obj, form, change) 
            # if that worked, deal with m2m field
            obj.user_profiles.clear()
            for user_profile in form.cleaned_data['user_profiles']:
                 obj.user_profiles.add(user_profile)
    
        def get_form(self, request, obj=None, **kwargs):
            if obj:
                self.form.base_fields['user_profiles'].initial = [ o.pk for o in obj.userprofile_set.all() ]
            else:
                self.form.base_fields['user_profiles'].initial = []
            return super(SiteAdmin, self).get_form(request, obj, **kwargs)
    

    This uses the same widget as the filter_horizontal setting, but hard-coded into the form.

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