1

I've found similar questions and answers, but none seems exactly right. I've got an abstract base model like so:

class BaseModel(models.Model):
    timestamp = models.DateTimeField(auto_now_add=True)
    modified = models.DateTimeField(auto_now=True)
    description = models.CharField(max_length=512, blank=True, null=True, help_text='Help')

    class Meta:
        abstract = True

And then I'm inheriting from it:

class AnotherModel(BaseModel):
    field1 = models.CharField(max_length=512)

But I want this model's help_text on the description field to be something else, like help_text='Some other help text'

What's the best way to do this? Can I override options on fields from inherited models?

nicorellius
  • 3,715
  • 4
  • 48
  • 79

1 Answers1

2

If this is really about the help text, I suggest to just override the ModelForm. However, you can use a factory and return the inner class:

def base_factory(description_help: str = "Standard text"):
    class BaseModel(models.Model):
        timestamp = models.DateTimeField(auto_now_add=True)
        modified = models.DateTimeField(auto_now=True)
        description = models.CharField(
            max_length=512, blank=True, null=True, help_text=description_help
        )

        class Meta:
            abstract = True

    return BaseModel


class ConcreteModel(base_factory("Concrete help")):
    field1 = ...
  • The `help_text` was just an example, so your providing a generalized answer is much appreciated. I may be doing things incorrectly, but in some cases, overriding only the field options on the child class seems warranted (eg, Django admin). This looks like an interesting solution. – nicorellius Oct 29 '20 at 15:39
  • No it's common. But I tend to restrict the base class to only the fields that are going to be customizable. It's easy to mix multiple. For example, I often use `name = models.CharField()` (category name, shirt name, dog name, you name it). But length may vary, so you use this pattern to control the max length. –  Oct 29 '20 at 15:47
  • Yes, exactly. This is basically what I'm doing: modified, timestamp, name, and description in my particular case. So to make this more general, I'd just add more arguments to the `base_factory`? Like `def base_factory(description_help: str = "Help", name_default: str = "Name" ):`, etc? – nicorellius Oct 29 '20 at 15:58
  • 1
    Yep, exactly. If you get over 5 arguments, you probably want to separate one or more fields out, but that's just a rule of thumb not some golden standard. Just understand that the more arguments you pack into one factory, the less chance it remains widely reusable. –  Oct 29 '20 at 17:02
  • Thanks again for your help on this. I ended up using the `ModelForm` `help_texts` attribute for the help text, but this idea of a model factory has really helped me in other places. Cheers. – nicorellius Nov 08 '20 at 19:31