|  | 30 | class Author(models.Model): | 
          
            |  | 31 | name = models.CharField(max_length=30) | 
          
            |  | 32 |  | 
          
            |  | 33 | # Missing unique_together in the intermediate model: | 
          
            |  | 34 |  | 
          
            |  | 35 | class Book(models.Model): | 
          
            |  | 36 | name = models.CharField(max_length=20) | 
          
            |  | 37 | authors = models.ManyToManyField(Author, through='AuthorsBooks') | 
          
            |  | 38 |  | 
          
            |  | 39 | class AuthorsBooks(models.Model): | 
          
            |  | 40 | author = models.ForeignKey(Author) | 
          
            |  | 41 | book = models.ForeignKey(Book) | 
          
            |  | 42 |  | 
          
            |  | 43 | # Extra data in the intermediate model: | 
          
            |  | 44 |  | 
          
            |  | 45 | class Ballad(models.Model): | 
          
            |  | 46 | name = models.CharField(max_length=20) | 
          
            |  | 47 | authors = models.ManyToManyField(Author, through='AuthorsBallads') | 
          
            |  | 48 |  | 
          
            |  | 49 | class AuthorsBallads(models.Model): | 
          
            |  | 50 | author = models.ForeignKey(Author) | 
          
            |  | 51 | ballad = models.ForeignKey(Ballad) | 
          
            |  | 52 | extra_data = models.IntegerField() | 
          
            |  | 53 |  | 
          
            |  | 54 | class Meta: | 
          
            |  | 55 | unique_together = ('author', 'ballad') | 
          
            |  | 56 |  | 
          
            |  | 57 | # Intermediate model PK field isn't an independent one: | 
          
            |  | 58 |  | 
          
            |  | 59 | class Act(models.Model): | 
          
            |  | 60 | name = models.CharField(max_length=20) | 
          
            |  | 61 | authors = models.ManyToManyField(Author, through='AuthorsActs') | 
          
            |  | 62 |  | 
          
            |  | 63 | class AuthorsActs(models.Model): | 
          
            |  | 64 | author = models.ForeignKey(Author, primary_key=True) | 
          
            |  | 65 | act = models.ForeignKey(Act) | 
          
            |  | 66 |  | 
          
            |  | 67 | # This through-using m2m complies with all the requirements needed to be | 
          
            |  | 68 | # listed in ModelAdmin.fields, should validate succesfully: | 
          
            |  | 69 |  | 
          
            |  | 70 | class Paper(models.Model): | 
          
            |  | 71 | name = models.CharField(max_length=20) | 
          
            |  | 72 | authors = models.ManyToManyField(Author, through='AuthorsPapers') | 
          
            |  | 73 |  | 
          
            |  | 74 |  | 
          
            |  | 75 | class AuthorsPapers(models.Model): | 
          
            |  | 76 | author = models.ForeignKey(Author) | 
          
            |  | 77 | paper = models.ForeignKey(Paper) | 
          
            |  | 78 |  | 
          
            |  | 79 | class Meta: | 
          
            |  | 80 | unique_together = ('author', 'paper') | 
          
            |  | 81 |  | 
          
            |  | 82 | # Intermediate model has a manually set PK, should work too: | 
          
            |  | 83 |  | 
          
            |  | 84 | class Post(models.Model): | 
          
            |  | 85 | name = models.CharField(max_length=20) | 
          
            |  | 86 | authors = models.ManyToManyField(Author, through='AuthorsPosts') | 
          
            |  | 87 |  | 
          
            |  | 88 |  | 
          
            |  | 89 | class AuthorsPosts(models.Model): | 
          
            |  | 90 | mypk = models.AutoField(primary_key=True) | 
          
            |  | 91 | author = models.ForeignKey(Author) | 
          
            |  | 92 | post = models.ForeignKey(Post) | 
          
            |  | 93 |  | 
          
            |  | 94 | class Meta: | 
          
            |  | 95 | unique_together = ('author', 'post') | 
          
            |  | 96 |  | 
          
            |  | 97 | # Recursive m2m with through, should work too: | 
          
            |  | 98 |  | 
          
            |  | 99 | class Writer(models.Model): | 
          
            |  | 100 | name = models.CharField(max_length=30) | 
          
            |  | 101 | similar = models.ManyToManyField('self', through='Influence', symmetrical=False) | 
          
            |  | 102 |  | 
          
            |  | 103 |  | 
          
            |  | 104 | class Influence(models.Model): | 
          
            |  | 105 | inspirator = models.ForeignKey(Writer, related_name='influenced_by') | 
          
            |  | 106 | inspired = models.ForeignKey(Writer, related_name='influenced') | 
        
        
          
            |  | 176 | # Regression test for #12203 - Fail more gracefully when a M2M field that | 
          
            |  | 177 | # specifies the 'through' option is included in the 'fields' ModelAdmin option. | 
          
            |  | 178 |  | 
          
            |  | 179 | >>> class BookAdmin(admin.ModelAdmin): | 
          
            |  | 180 | ...     fields = ['authors'] | 
          
            |  | 181 |  | 
          
            |  | 182 | >>> validate(BookAdmin, Book) | 
          
            |  | 183 | Traceback (most recent call last): | 
          
            |  | 184 | ... | 
          
            |  | 185 | ImproperlyConfigured: BookAdmin.fields: Included 'authors' ManyToManyField field uses 'through' option but specifies a non suitable intermediate model (AuthorsBooks). | 
          
            |  | 186 |  | 
          
            |  | 187 | >>> class BalladAdmin(admin.ModelAdmin): | 
          
            |  | 188 | ...     fields = ['authors'] | 
          
            |  | 189 |  | 
          
            |  | 190 | >>> validate(BalladAdmin, Ballad) | 
          
            |  | 191 | Traceback (most recent call last): | 
          
            |  | 192 | ... | 
          
            |  | 193 | ImproperlyConfigured: BalladAdmin.fields: Included 'authors' ManyToManyField field uses 'through' option but specifies a non suitable intermediate model (AuthorsBallads). | 
          
            |  | 194 |  | 
          
            |  | 195 | >>> class ActAdmin(admin.ModelAdmin): | 
          
            |  | 196 | ...     fields = ['authors'] | 
          
            |  | 197 |  | 
          
            |  | 198 | >>> validate(ActAdmin, Act) | 
          
            |  | 199 | Traceback (most recent call last): | 
          
            |  | 200 | ... | 
          
            |  | 201 | ImproperlyConfigured: ActAdmin.fields: Included 'authors' ManyToManyField field uses 'through' option but specifies a non suitable intermediate model (AuthorsActs). | 
          
            |  | 202 |  | 
          
            |  | 203 | >>> class PaperAdmin(admin.ModelAdmin): | 
          
            |  | 204 | ...     fields = ['authors'] | 
          
            |  | 205 |  | 
          
            |  | 206 | >>> validate(PaperAdmin, Paper) | 
          
            |  | 207 |  | 
          
            |  | 208 | >>> class PostAdmin(admin.ModelAdmin): | 
          
            |  | 209 | ...     fields = ['authors'] | 
          
            |  | 210 |  | 
          
            |  | 211 | >>> validate(PostAdmin, Post) | 
          
            |  | 212 |  |