Opened 17 years ago
Last modified 5 weeks ago
#5793 assigned New feature
Allow custom attributes in Meta classes
Reported by: | Owned by: | ||
---|---|---|---|
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, bcail, Piotr Kubiak, Clifford Gama | 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 (31)
comment:1 by , 17 years ago
Resolution: | → wontfix |
---|---|
Status: | new → closed |
comment:2 by , 15 years ago
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 by , 15 years ago
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 by , 15 years ago
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 by , 15 years ago
Inspired by the django-easytree code, I've created django-immutablefield for anyone interested.
comment:6 by , 11 years ago
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.
follow-up: 8 comment:7 by , 11 years ago
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 by , 11 years ago
comment:11 by , 9 years ago
Cc: | 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 by , 9 years ago
Cc: | removed |
---|---|
Easy pickings: | set |
comment:13 by , 9 years ago
Component: | Metasystem → Database layer (models, ORM) |
---|---|
Easy pickings: | unset |
comment:14 by , 9 years ago
Cc: | 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 by , 8 years ago
Cc: | added |
---|
comment:16 by , 8 years ago
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 by , 8 years ago
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 by , 8 years ago
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 by , 7 years ago
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 by , 6 years ago
Cc: | added |
---|
comment:21 by , 6 years ago
Cc: | added |
---|
comment:22 by , 6 years ago
Cc: | added |
---|
comment:23 by , 5 years ago
Cc: | added |
---|
comment:24 by , 4 years ago
Cc: | added |
---|
comment:25 by , 3 years ago
Cc: | added |
---|
comment:26 by , 2 years ago
Owner: | changed from | to
---|---|
Status: | new → assigned |
follow-up: 31 comment:27 by , 2 years ago
Saeed, I removed your comment because you remove the ticket description. Please don't do this.
comment:28 by , 2 years ago
Dear Saeed, typically that would be intended for reusable 3rd party apps to pick up rather than ordinary apps, but yes the idea is not to be limited to the built-in attributes.
The main challenge is to find an elegant way to register new attributes (so the system that reports typos still works) and that kicks in at the right time to be useful, I mentioned above that I suspect AppConfig.__init__()
will work but that would have to be checked.
As Dylan mentioned, we also need to see how this interacts with the migration framework, especially the ORM inside RunPython.
comment:29 by , 2 years ago
I have studied a lot about the Meta
class.
I disabled the typo section and added my new attribute, but unfortunately, I didn't get any results.
About AppConfig.__init__()
, I honestly didn't understand and I need your guidance.
Do you have enough time to explain more? Can you give me an example to implement it?
comment:31 by , 2 years ago
Dear Mariusz
This would be a very cool feature to add to Django.
I have enough time to do this and I am very eager to do it.
Can you give me more guidance to get a good result (about connecting custom attributes to the migration framework)
comment:32 by , 12 months ago
Cc: | added |
---|
comment:33 by , 2 months ago
Cc: | added |
---|
comment:34 by , 5 weeks ago
Cc: | 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.