Opened 8 years ago

Last modified 10 months ago

#5793 new New feature

Allow custom attributes in Meta classes

Reported by: eikke@… Owned by: nobody
Component: Metasystem Version: master
Severity: Normal Keywords:
Cc: Triage Stage: Accepted
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no


In some cass it is useful to be able to store meta information on models inside the model class. In Django the Meta subclass is used to achieve this. Trying to add a custom attribute to a model's Meta inner class results in an exception though, thrown from django.db.models.options, which does indeed check any valid attribute names and raises an exception when unknown names are found.
Is there any reason for this somewhat strange behaviour, not to allow a developer to add non-standard meta information to a model class (which can later on be used in eg view code)?


Change History (10)

comment:1 Changed 8 years ago by ubernostrum

  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset
  • Resolution set to wontfix
  • Status changed from new to closed

I'm going to call this a wontfix; Meta exists to set up a lot of "internal use" APIs, and the validation has to be strict to ensure that potential errors in that process are caught (e.g., if your Meta contains an attribute order, how can the validator tell whether you meant to add your own custom info or actually wanted ordering?).

And given that Django models are simply Python classes, and you're free to set up any attributes on them you like and then make use of them, I'm not sure that the use case of adding custom information in Meta is compelling enough.

comment:2 Changed 6 years ago by miracle2k

  • Resolution wontfix deleted
  • Status changed from closed to reopened

I'd like to ask this be given another thought.

I'm not really convinced by the validation argument; first, this seems a more basic problem at it's core, particular in scripting languages. There are lots of places where a typo could lead to an API silently not being activated (think certain kwargs-scenarios, or a typo in the name of subclass methods etc). At some point you just need to actually check whether the code you've written actually does what its supposed to.

Secondly, if one really wants meta-validation, there is a middle ground: Require custom meta attributes to be pre-registered.

I just think this would be really nice for libraries that provide model base classes to accept configuration. Say for example django-treebeard and it's node_order_by (which is currently simply added to the class itself, which works, yes, but there's a reason why we have Meta in the first place).

comment:3 Changed 6 years ago by ubernostrum

  • Resolution set to wontfix
  • Status changed from reopened to closed

If you disagree with a wontfix designation, the correct place to bring it up is on the django-developers list.

comment:4 Changed 6 years ago by miracle2k

For those Googling, it turns out there is a way to work around this using a custom model metaclass:

comment:5 Changed 5 years ago by robmadole

Inspired by the django-easytree code, I've created django-immutablefield for anyone interested.

comment:6 Changed 2 years ago by russellm

  • Easy pickings unset
  • Resolution wontfix deleted
  • Severity set to Normal
  • Status changed from closed to new
  • Triage Stage changed from Unreviewed to Accepted
  • Type set to New feature
  • UI/UX unset

This ticket was raised on Django-developers in response to a duplicated report (#21081). The devil is in the details, but I can at least see that there is a use case here. I share @ubernostrum's concern about Meta becoming a dumping ground for flags that shouldn't be kept on Meta, but it doesn't follow that there is no reason why an end-user would want to define an extension to the built-in set.

comment:7 follow-up: Changed 2 years ago by shai

On the list, Tim Chase gave this example:

class MyModel(Model):
  class Meta:
    class MyApp:
      secure_fields = ["cc_num", "ssn"]

The idea was that app-specific properties should be namespaced to avoid clashes. I think the approach is fine, I just don't see why these classes need to be in Meta; I see nothing wrong with

class MyModel(Model):
  class Meta:
  class MyApp:
    secure_fields = ["cc_num", "ssn"]

This leaves the app-specific metadata separate from fields and methods, so the "API" is clean enough; it avoids clashes reasonably well; and it requires no changes in Django.

Note that this was the approach taken by Admin at first -- and my impression (though I wasn't "there" at the time) is that it changed because Admin classes became too large for comfort as nested classes, not because the first idea was considered so bad.

I think for most use-cases -- in particular, including the two noted on the list, marking fields as "to be published" or "to be censored", this can work well.

The point about extending the ORM stands, but this does not seem to be the use-case that motivates the current requests.

comment:8 in reply to: ↑ 7 Changed 2 years ago by shai

Replying to shai:

The point about extending the ORM stands, but this does not seem to be the use-case that motivates the current requests.

I have to take that back -- it is true as far as the requests on the mailing list postings are concerned, but #21081 actually is about extending the ORM.

comment:9 Changed 10 months ago by bronger

The non-nested MyApp doesn't seem to be inherited.

comment:10 Changed 10 months ago by bronger

Forget comment:9, I was wrong.

Note: See TracTickets for help on using tickets.
Back to Top