                          found = True
                  elif link_field_name is None or link_field_name == f.name:
                      setattr(self, cache_attr, getattr(f, attr))
                      break
          try:
              return getattr(self, cache_attr)
          except AttributeError:
              # We only reach here if we're given an invalid reverse field
              # name via the `through_fields` argument
              raise FieldDoesNotExist(link_field_name)
  
      def value_to_string(self, obj):
          data = ''
          if obj:
              qs = getattr(obj, self.name).all()
 
</s> remove         # We only reach here if we're given an invalid field name via the
        # `through_fields` argument
        raise FieldDoesNotExist(link_field_name)
 </s> add  </s> remove         elif self.rel.through_fields is not None:
            if not len(self.rel.through_fields) >= 2 or not (self.rel.through_fields[0] and self.rel.through_fields[1]):
                errors.append(
                    checks.Error(
                        ("The field is given an iterable for through_fields, "
                         "which does not provide the names for both link fields "
                         "that Django should use for the relation through model "
                         "'%s'.") % qualified_model_name,
                        hint=None,
                        obj=self,
                        id='fields.E337',
                    )
                )

        elif not isinstance(self.rel.through, six.string_types):
 </s> add         else: </s> remove         with self.assertRaisesMessage(FieldDoesNotExist, 'invalid_field'):
            Event().invitees.all()
 </s> add         field = Event._meta.get_field('invitees')
        errors = field.check(from_model=Event)
        expected = [
            Error(
                ("The intermediary model 'invalid_models_tests.Invitation' has no field 'invalid_field_1'."),
                hint="Did you mean one of the following foreign keys to 'Event': event?",
                obj=field,
                id='fields.E338'),
            Error(
                ("The intermediary model 'invalid_models_tests.Invitation' has no field 'invalid_field_2'."),
                hint="Did you mean one of the following foreign keys to 'Fan': invitee, inviter?",
                obj=field,
                id='fields.E338'),
        ]
        self.assertEqual(expected, errors) </s> remove         with self.assertRaisesMessage(FieldDoesNotExist, 'invalid_field'):
            Event().invitees.all()
 </s> add         field = Event._meta.get_field('invitees')
        errors = field.check(from_model=Event)
        expected = [
            Error(
                ("'Invitation.invitee' is not a foreign key to 'Event'."),
                hint="Did you mean one of the following foreign keys to 'Event': event?",
                obj=field,
                id='fields.E339'),
            Error(
                ("'Invitation.event' is not a foreign key to 'Fan'."),
                hint="Did you mean one of the following foreign keys to 'Fan': invitee, inviter?",
                obj=field,
                id='fields.E339'),
        ]
        self.assertEqual(expected, errors) </s> remove                 ("The field is given an iterable for through_fields, "
                 "which does not provide the names for both link fields "
                 "that Django should use for the relation through model "
                 "'invalid_models_tests.Invitation'."),
                hint=None,
 </s> add                 ("Field specifies 'through_fields' but does not provide the names "
                 "of the two link fields that should be used for the relation "
                 "through model 'invalid_models_tests.Invitation'."),
                hint=("Make sure you specify 'through_fields' as "
                      "through_fields=('field1', 'field2')"),
        return getattr(self, cache_attr)
                          found = True
                  elif link_field_name is None or link_field_name == f.name:
                      setattr(self, cache_attr, getattr(f, attr))
                      break
        return getattr(self, cache_attr)
        return getattr(self, cache_attr)
        return getattr(self, cache_attr)
        return getattr(self, cache_attr)
        return getattr(self, cache_attr)
        return getattr(self, cache_attr)
  
      def value_to_string(self, obj):
          data = ''
          if obj:
              qs = getattr(obj, self.name).all()
keep keep keep keep replace replace replace replace replace replace keep keep keep keep keep
 Fixed #22217 - ManyToManyField.through_fields fixes.

- Docs description of arguments mix up.
- Keep it from erroneously masking E332 check.
- Add checks E338 and E339, tweak message of E337. 
django/db/models/fields/related.py