5

I have the following models:

from django.db import models
from foo.bar.models import Location


class AbstractShop(models.Model):
    location = models.ForeignKey(Location, on_delete=models.CASCADE, related_name="%(class)s")

    class Meta(self):
        abstract = True


class Bakery(AbstractShop):
    some_field = models.BooleanField("Some field", default=True)

    class Meta:
        verbose_name = "Bakery"
        verbose_name_plural = "Bakeries"


class Supermarket(AbstractShop):
    some_other_field = models.CharField("Some other field", max_length=20)

    class Meta:
        verbose_name = "Supermarket"
        verbose_name_plural = "Supermarkets"

Now, Supermarket as well as Bakery inherit the location-ForeignKey from AbstractShop.
If I want to query the reverse relation to Bakery on the Location model, I would have to use bakerys (instead of the correct bakeries) as related_name - which I don't want as it's grammatically wrong and unintuitive.

So my questions are:

  1. Is there any way to use the verbose_name_plural as related_name?

  2. Is there any way at all to use any other related_name than "%(class)s" or "%(app_label)s or do I just have to implement the ForeignKey on the child classes?

If so, that would be somewhat annoying. Imagine you have a lot of shared ForeignKeys: You can move the ones with regular plurals in English to the abstract base class (ABC) (because for regular nouns the added "s" in "%(class)s" results in the correct plural form) while those with irregular plurals have to be implemented on the child class (as only there the related_name can be set to the plural of the actual name of the child class, which you don't know in the ABC).
This is a totally arbitrary condition which might not be obvious to non-native English speakers, also it transfers linguistic logic to code, which IMHO shouldn't happen.

C4X
  • 87
  • 8
  • I've not tried this, but I'd kind of expect it to set it automatically if you don't set `related_name` to anything on the ABC ... What actually happens if you leave that off the ABC definition? – michjnich Oct 01 '20 at 10:34
  • It defaults to `location_set` as related name as described in the [documentation](https://docs.djangoproject.com/en/3.1/topics/db/queries/#related-objects) – C4X Oct 01 '20 at 10:52
  • I don't suppose setting it to `$(verbose_name_plural)` works by any chance? I'm rather curious as to whether there's a solution to this as I can see me wanting it at some point! – michjnich Oct 01 '20 at 12:05
  • I found this from 5 years back : https://stackoverflow.com/questions/30343212/foreignkey-field-related-to-abstract-model-in-django "It's not possible to install Foreign Keys to abstract models in Django" - Not sure if this still holds in 3.1 or not... – michjnich Oct 01 '20 at 12:22
  • I think it still holds, but it's a different case. Note that I'm not trying to set a ForeignKey to an abstract model (which can't work, as the abstract model doesn't have an associated database table - that's the whole point of abstract models), but rather define a ForeignKey to a normal model in the abstract base class. The child models, which are normal models, will inherit this ForeignKey and then have a normal ForeignKey to another normal model (Location). – C4X Oct 01 '20 at 14:01
  • Ever find a nice solution to this? I've only come up with hacky solutions I wouldn't actually want to use – user319862 Apr 15 '21 at 18:05
  • @user319862 A bit late here, but from what I can tell there is no solution except to create a custom ForeignKey field and override the RelatedField `contribute_to_class()` method from `django.db.models.fields.related` as explained [here](https://stackoverflow.com/questions/52119678/how-to-customize-related-name-argument-in-django/52121866#52121866). This is where the class interpolation options for `class`, `model_name` and `app_label` are set. I haven't tried this myself however and have no idea if it would break anything else that relies on related name. I really wish there were more options – wjh18 Feb 27 '22 at 15:37

0 Answers0