Opened 15 years ago
Last modified 9 months ago
#5793 new New feature
Allow custom attributes in Meta classes
Reported by: | Owned by: | nobody | |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | dev |
Severity: | Normal | Keywords: | |
Cc: | Loic Bistuer, jamespic@…, Ryan Hiebert, Rich Rauenzahn, Carlos Palol, Sardorbek Imomaliev, Gordon Wrigley, omelched | Triage Stage: | Accepted |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
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)?
Thanks!
Change History (23)
comment:1 Changed 14 years ago by
Resolution: | → wontfix |
---|---|
Status: | new → closed |
comment:2 Changed 12 years ago by
Resolution: | wontfix |
---|---|
Status: | closed → 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 12 years ago by
Resolution: | → wontfix |
---|---|
Status: | reopened → closed |
If you disagree with a wontfix designation, the correct place to bring it up is on the django-developers list.
comment:4 Changed 12 years ago by
For those Googling, it turns out there is a way to work around this using a custom model metaclass:
http://bitbucket.org/fivethreeo/django-easytree/src/7ab11cd55b09/easytree/models.py
comment:5 Changed 12 years ago by
Inspired by the django-easytree code, I've created django-immutablefield for anyone interested.
comment:6 Changed 9 years ago by
Easy pickings: | unset |
---|---|
Resolution: | wontfix |
Severity: | → Normal |
Status: | closed → new |
Triage Stage: | Unreviewed → Accepted |
Type: | → 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: 8 Changed 9 years ago by
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 Changed 9 years ago by
comment:11 Changed 6 years ago by
Cc: | Simon Litchfield added |
---|
+1 - it's kinda daft to encourage the ORM to be extendable, while at the same time restricting what Meta options we're allowed
Why not just move DEFAULT_NAMES into the Model class? problem solved, zero breakage.
comment:12 Changed 6 years ago by
Cc: | Simon Litchfield removed |
---|---|
Easy pickings: | set |
comment:13 Changed 6 years ago by
Component: | Metasystem → Database layer (models, ORM) |
---|---|
Easy pickings: | unset |
comment:14 Changed 6 years ago by
Cc: | Loic Bistuer added |
---|
How about an API to register new model options (e.g. models.Options.register_option('mptt_manager_name')
).
The AppConfig.ready()
comes in too late to register this, but AppConfig.__init__()
should work.
comment:15 Changed 5 years ago by
Cc: | jamespic@… added |
---|
comment:16 Changed 5 years ago by
Question: is this ticket just about Model.Meta or also for ModelForm.Meta ? /me wondering if another, similar ticket could be opened about ModelForm.Meta
comment:17 Changed 5 years ago by
James I think this ticket is about Model.Meta but whatever the API it ends up with could be copied over to ModelForm.Meta, so idk if it makes sense to create a second ticket for that yet
comment:18 Changed 5 years ago by
It would be indeed very useful: I have a custom database backend (for Redshift) and I would like to support advanced options for this backend (these options would modify the SQL for table creation for instance). There is apparently no other way than defining that on the Meta dict (due to the migration system) but it is not possible to define custom options.
Did you guys agree on the design yet?
comment:19 Changed 5 years ago by
This would actually enable users to develop on Django much more easily; I imagine you would get a slew of new ORM developments coming in quite quickly.
Some thoughts:
1) How to hook into the migration system for database changes? i.e. If I wanted to add partial indices and have the migrations autogenerate from my custom Meta option for this. The 'register_option' idea is probably good for this.
2) How to play nice with migrations for state changes?
comment:20 Changed 4 years ago by
Cc: | Ryan Hiebert added |
---|
comment:21 Changed 3 years ago by
Cc: | Rich Rauenzahn added |
---|
comment:22 Changed 3 years ago by
Cc: | Carlos Palol added |
---|
comment:23 Changed 2 years ago by
Cc: | Sardorbek Imomaliev added |
---|
comment:24 Changed 18 months ago by
Cc: | Gordon Wrigley added |
---|
comment:25 Changed 9 months ago by
Cc: | omelched added |
---|
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 yourMeta
contains an attributeorder
, how can the validator tell whether you meant to add your own custom info or actually wantedordering
?).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.