title: django drf serializer with a many-to-many model (with extra data)
body: <p>NOTE:  this isn't really about getting Django's intermediate model for many-to-many relationship with extra fields to work.  this is about how to use Django Rest Framework's Serializers.ModelSerializer with an intermediate model.
  I have these models (and more):</p>
  
  <pre><code>class Method(models.Model):
      name = models.CharField(max_length=50, unique=True)
      descripton = models.TextField(null=False)
  
  class Version(models.Model):
      version_number = models.CharField(max_length=50)
      cmd_line_script = models.CharField(max_length=250, null=False)
      SOP = models.TextField(null=False)
      FK_method = models.ForeignKey(Method, on_delete=models.CASCADE)
  
      class Meta:
          unique_together = ('version_number', 'FK_method')
  
  class Instrument(models.Model):
      serial_number = models.CharField(max_length=50, unique=True)
      asset_number = models.CharField(max_length=50, unique=True)
      name = models.CharField(max_length=50)
      checksum_string = models.CharField(max_length=128, null=True)
      FK_instr_type = models.ForeignKey(InstrType, related_name='installations', on_delete=models.PROTECT)
      Instr_Version = models.ManyToManyField(
                          Version, 
                          through='Instr_Version', 
                          related_name = 'Instr_Version',
                      )
  
  class Instr_Version(models.Model):
      FK_version = models.ForeignKey(Version, on_delete=models.CASCADE)
      FK_instrument = models.ForeignKey(Instrument, on_delete=models.CASCADE)
      validating_user = models.ForeignKey(UserProfile, on_delete=models.PROTECT)
      timestamp = models.DateField(auto_now_add=True)
  
      class Meta:
          unique_together = ('FK_version', 'FK_instrument')
  </code></pre>
  
  <p>and they're fine.  I'm trying to use the <code>[Django-Rest-Framework serializers][1]</code> to serialize through the Instr_Version table so an api can retrieve a json representation of all the versions (and their FK_method data, via a MethodSerializer) that are listed as valid for that instrument.
  I have these serializers so far (and a couple more for InstrType, UserProfile, etc)</p>
  
  <pre><code>class MethodSerializer(serializers.ModelSerializer):
      class Meta:
          model = Method
          fields = ('id', 'name', 'description', 'version_set')
  
  class VersionSerializer(serializers.ModelSerializer):
      method = MethodSerializer(read_only=True)
      #Instr_Version = Instr_VersionSerializer(source='Instr_Version_set', many=True, read_only=True)
      class Meta:
          model = Version
          fields = ('id', 'method', 'version_number', 'cmd_line_script', 'SOP')
  
  class Instr_to_VersionSerializer(serializers.ModelSerializer):
      version = VersionSerializer(source='FK_version_id', read_only=True, many=False)
      validator = UserProfileSerializer(source='validating_user', read_only=True)
  
      class Meta:
          model = Instr_Version
          fields = ('id', 'version', 'validator', 'timestamp')
  
  
  class InstrumentSerializer(serializers.ModelSerializer):
      instr_type = InstrTypeSerializer(source='FK_instr_type', read_only=True)
      Validated_Versions = Instr_to_VersionSerializer(source='Instr_Version', many=True, read_only=True)
  
      class Meta:
          model = Instrument
          fields = ('id', 'asset_number', 'serial_number', 'name', 'checksum_string', 'instr_type', 'Validated_Versions')
  </code></pre>
  
  <p>The closest I've gotten is that a GET like: "api/getInstrument/?asset_number=1234"
  results in:</p>
  
  <pre><code>{
      "id": 11,
      "asset_number": "1234",
      "serial_number": "1234",
      "name": "Instrument1",
      "checksum_string": "0123456789ABCDEF0123",
      "instr_type": {
          "id": 70,
          "make": "Make1",
          "model": "Model1",
          "service_email": "model1@company.com",
          "service_website": "www.model1.com"
      },
      "Validated_Versions": [{
          "id": 9
      }, {
          "id": 10
      }, {
          "id": 12
      }]
  }
  </code></pre>
  
  <p>Which is pretty good, but the validated_versions array should have a lot more data than just an 'id'.</p>
  
  <p>I tried adding/removing the <code>id</code> from the fields list in <code>Instr_to_VersionSerializer</code> and <code>VersionSerializer</code> for experiment's sake.  evidence says that the <code>id</code> in the fields list within <code>Instr_to_VersionSerializer</code> is actually printing the <code>FK_version_id</code> on the <code>Instr_Version</code> model (or the PK on the Version model), not the PK of <code>Instr_Version</code> like I had expected.  This made me think that DJR was 'automatically' seeing through the many-to-many, straight to the <code>Version</code> model, so I tried changing <code>Instr_to_VersionSerializer</code> to:</p>
  
  <pre><code>class Instr_to_VersionSerializer(serializers.ModelSerializer):
      #version = VersionSerializer(source='FK_version_id', read_only=True, many=False)
      validator = UserProfileSerializer(source='validating_user', read_only=True)
      #method = MethodSerializer(read_only=True)
  
      class Meta:
          model = Instr_Version
          fields = ('id', 'version_number', 'cmd_line_script', 'SOP', 'validator', 'timestamp')
  </code></pre>
  
  <p>Which would leave the VersionSerializer out of it entirely, but I get a <code>Field name</code>version_number<code>is not valid for model</code>Instr_Version<code>.</code> error, so I'm not sure what's going on.</p>
  
  <p>One final attempt myself was to change the <code>source</code> for the <code>version = VersionSerializer</code> to <code>versions</code>, which is the reverse relationship.  this seemed illogical, but I'm at that point where I'm trying anything.  result was: an error that <code>version_number</code> was not a valid field, which told me I was finally getting to the <code>VersionSerializer</code>, so I commented out most of the fields in <code>VersionSerializer</code> just to see what was happening, but this only led to: 
  <code>"Validated_Versions":[{"id":9,"version":{}},{"id":10,"version":{}},{"id":12,"version":{}}]</code></p>