Opened 14 years ago
Closed 12 years ago
#14018 closed New feature (wontfix)
Introduce class_plural %-substitution placeholder for related_name of ForeignKey/ManyToManyField
Reported by: | Xiao Di Guan | Owned by: | nobody |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | dev |
Severity: | Normal | Keywords: | related_name, ManyToManyField, ForeignKey, abstract base class |
Cc: | Triage Stage: | Design decision needed | |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | yes |
Easy pickings: | no | UI/UX: | no |
Description
Django 1.2 introduced two %-substitution placeholders, %(class)s
and %(app_label)s
, to work around uniqueness issues when a custom related_name
for a ForeignKey
or ManyToManyField
defined in an abstract base class is inherited by multiple child classes.
Quoting from Django's models documentation, "It's suggested ![...] that the name of a ManyToManyField
![...] be a plural describing the set of related model objects." Given the nature of a ManyToManyField
, it may be preferable to reciprocate this pluralized field naming style through related_name
. By introducing a third %-substitution placeholder, %(class_plural)s
, this can be accomplished.
Consider the following snippet:
class Tag(models.Model): slug = models.SlugField(max_length=63, unique=True) class Post(models.Model): slug = models.SlugField(max_length=127, unique=True) tags = models.ManyToManyField(Tag, related_name='%(class_plural)s') # docs suggest related_name='%(app_label)s_%(class)s_related' class Meta: abstract = True class Entry(Post): title = models.CharField(max_length=255) content = models.TextField() class Meta: verbose_name_plural = 'entries' class Event(Post): summary = models.CharField(max_length=255) start_date = models.DateTimeField()
Arguably, tag.entries
and tag.events
are more semantic than either tag.entry_set
and tag.event_set
or tag.appname_entry_related
and tag.appname_event_related
.
Ultimately, the introduction of a %(class_plural)s
%-substitution placeholder provides greater flexibility when designing models with abstract base classes and ForeignKeys or ManyToManyFields.
Attachments (1)
Change History (10)
by , 14 years ago
Attachment: | changes.diff added |
---|
follow-up: 4 comment:1 by , 14 years ago
I don't think using verbose_name_plural as part of the related_name is a good idea. If you have a model named SpecialEntry, the default verbose_name will be 'special entry' and verbose_name_plural will be 'special entrys'.
comment:2 by , 14 years ago
Making code (attribute names) dependent on the result of a translation is quite a stupid idea. verbose_name_plural might evaluate to other translations depending on settings.LANGUAGE_CODE, might contain special chars and whitespace and isn't suitable at all for naming class attributes (i.e. related_name).
I'm quite sure this is "wontfix" material.
comment:3 by , 14 years ago
Patch needs improvement: | set |
---|---|
Triage Stage: | Unreviewed → Design decision needed |
The patch "as is" surely needs improvement. A simple solution that comes to mind would be adding name_plural
to Meta. Then %(class_plural)
could be replaced with that value or with class' name with an "s" added. The example above would then look something like this:
class Tag(models.Model): slug = models.SlugField(max_length=63, unique=True) class Post(models.Model): slug = models.SlugField(max_length=127, unique=True) tags = models.ManyToManyField(Tag, related_name='tagged_%(class_plural)s') class Meta: abstract = True class Entry(Post): title = models.CharField(max_length=255) content = models.TextField() class Meta: name_plural = "entries" # related attribute will be "tagged_entries" verbose_name_plural = _("Journal entries") class Event(Post): summary = models.CharField(max_length=255) start_date = models.DateTimeField() # related attribute will be "tagged_events"
I don't think much people care about this that much, so it's mostly a "nice to have" feature.
comment:4 by , 14 years ago
milestone: | 1.3 → 2.0 |
---|
Replying to anonymous and mk:
Good point; I hadn't considered verbose_name_plural
s with multiple and/or internationalised words.
Replying to lrekucki:
That's a rather elegant solution. I agree that it's more of a nice touch than a must-have feature, but I make use of this patch in my code, and don't believe there's any harm in including it.
Thanks for all the suggestions! I'm presently working on a patch with updated documentation and a set of test cases.
comment:5 by , 13 years ago
Severity: | → Normal |
---|---|
Type: | → New feature |
comment:5 by , 12 years ago
Resolution: | → wontfix |
---|---|
Status: | new → closed |
I'm going to close this ticket, because it proposes to hardcode one specific case, rather than provide an API to resolve the general problem.
There are several other tickets about related name with more general proposals.
Code and documentation patch