diff --git a/django/db/models/fields/related.py b/django/db/models/fields/related.py index 2b27b5a340..2f454e1246 100644 --- a/django/db/models/fields/related.py +++ b/django/db/models/fields/related.py @@ -586,9 +586,13 @@ class ReverseManyRelatedObjectsDescriptor(object): # ReverseManyRelatedObjectsDescriptor instance. def __init__(self, m2m_field): self.field = m2m_field + + def _through(self): # through is provided so that you have easy access to the through - # model (Book.authors.through) for inlines, etc. - self.through = m2m_field.rel.through + # model (Book.authors.through) for inlines, etc. This is done as + # a property to ensure that the fully resolved value is returned. + return self.field.rel.through + through = property(_through) def __get__(self, instance, instance_type=None): if instance is None: diff --git a/tests/regressiontests/admin_validation/models.py b/tests/regressiontests/admin_validation/models.py index 5506114841..93e3e065e6 100644 --- a/tests/regressiontests/admin_validation/models.py +++ b/tests/regressiontests/admin_validation/models.py @@ -26,6 +26,19 @@ class TwoAlbumFKAndAnE(models.Model): e = models.CharField(max_length=1) +class Author(models.Model): + name = models.CharField(max_length=100) + + +class Book(models.Model): + name = models.CharField(max_length=100) + authors = models.ManyToManyField(Author, through='AuthorsBooks') + + +class AuthorsBooks(models.Model): + author = models.ForeignKey(Author) + book = models.ForeignKey(Book) + __test__ = {'API_TESTS':""" @@ -95,4 +108,18 @@ Exception: ha >>> validate_inline(TwoAlbumFKAndAnEInline, None, Album) +# Regression test for #12203 -- If the explicitly provided through model +# is specified as a string, the admin should still be able use +# Model.m2m_field.through + +>>> class AuthorsInline(admin.TabularInline): +... model = Book.authors.through + +>>> class BookAdmin(admin.ModelAdmin): +... inlines = [AuthorsInline] + +# If the through model is still a string (and hasn't been resolved to a model) +# the validation will fail. +>>> validate(BookAdmin, Book) + """}