title: Django admin interface: using horizontal_filter with ManyToMany field with intermediate table
body: <p>I am trying to enhance the django admin interface similar to what has been done in the accepted answer of <a href="https://stackoverflow.com/questions/11657682/django-admin-interface-using-horizontal-filter-with-inline-manytomany-field">this SO post</a>. I have a many-to-many relationship between a <code>User</code> table and a <code>Project</code> table. In the django admin, I would like to be able to assign users to a project as in the image below:
  <a href="https://i.stack.imgur.com/mJL3H.png" rel="noreferrer"><img src="https://i.stack.imgur.com/mJL3H.png" alt="Widget to use in Project admin interface"></a></p>
  
  <p>It works fine with a simple <code>ManyToManyField</code> but the problem is that my model uses the <code>through</code> parameter of the <code>ManyToManyField</code> to use an intermediary table. I cannot use the <code>save_m2m()</code> and <code>set()</code> function and I am clueless on how to adapt the code below to make it work. </p>
  
  <p>The model: </p>
  
  <pre><code>class UserProfile(models.Model):
      user = models.OneToOneField(User, unique=True)
      projects = models.ManyToManyField(Project, through='Membership')
  
  class Project(models.Model):
      name = models.CharField(max_length=100, unique=True)
      application_identifier = models.CharField(max_length=100)
      type = models.IntegerField(choices=ProjectType)
      ...
  
  class Membership(models.Model):
      project = models.ForeignKey(Project,on_delete=models.CASCADE)
      user = models.ForeignKey(UserProfile,on_delete=models.CASCADE)
  
      # extra fields
      rating = models.IntegerField(choices=ProjectType)
      ...
  </code></pre>
  
  <p>The code used for the widget in <code>admin.py</code>:</p>
  
  <pre><code>from django.contrib.admin.widgets import FilteredSelectMultiple
  
  class ProjectAdminForm(forms.ModelForm):
      class Meta:
          model = Project
          fields = "__all__" # not in original SO post
  
      userprofiles = forms.ModelMultipleChoiceField(
          queryset=UserProfile.objects.all(),
          required=False,
          widget=FilteredSelectMultiple(
              verbose_name='User Profiles',
              is_stacked=False
          )
      )
  
      def __init__(self, *args, **kwargs):
          super(ProjectAdminForm, self).__init__(*args, **kwargs)
              if self.instance.pk:
                  self.fields['userprofiles'].initial = self.instance.userprofile_set.all()
  
      def save(self, commit=True):
          project = super(ProjectAdminForm, self).save(commit=False)  
          if commit:
              project.save()
  
          if project.pk:
              project.userprofile_set = self.cleaned_data['userprofiles']
              self.save_m2m()
  
          return project
  
  class ProjectAdmin(admin.ModelAdmin):
      form = ProjectAdminForm
      ...
  </code></pre>
  
  <p>Note: all the extra fields from the intermediary model do not need to be changed in the Project Admin view (they are automatically computed) and they all have a default value.  </p>
  
  <p>Thanks for your help! </p>