Code

Opened 9 years ago

Closed 8 years ago

#676 closed enhancement (invalid)

[patch] a _post_init hook for model classes to initialize fields from outside content

Reported by: hugo Owned by: adrian
Component: Metasystem Version:
Severity: normal Keywords:
Cc: Triage Stage: Unreviewed
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: UI/UX:

Description

It would be very interesting to have a _post_init hook. The reason for this is to pull stuff from outside into a model on field access. For example if you have tags to an object stored in a tagrelation table, but want to edit them in a textfield in the admin, you have the problem that the textfield might be out of sync with the real data. With a _post_init hook you could just pull in the tags from the tagrelations and populate that field with the correct string representation. And since you internally reference tags by the ID, this would even work if tag names or tag slugs are changed.

This could be implemented rather easily:

Index: core/meta/__init__.py
===================================================================
--- core/meta/__init__.py       (revision 987)
+++ core/meta/__init__.py       (working copy)
@@ -768,6 +768,8 @@
             raise TypeError, "'%s' is an invalid keyword argument for this function" % kwargs.keys()[0]
     for i, arg in enumerate(args):
         setattr(self, opts.fields[i].column, arg)
+    if hasattr(self, '_post_init'):
+        self._post_init()
 
 def method_eq(opts, self, other):
     return isinstance(other, self.__class__) and getattr(self, opts.pk.column) == getattr(other, opts.pk.column)

Attachments (0)

Change History (6)

comment:1 Changed 9 years ago by hugo

  • Summary changed from a _post_init hook for model classes to initialize fields from outside content to [patch] a _post_init hook for model classes to initialize fields from outside content

comment:2 Changed 9 years ago by ian@…

Hi Hugo.
won't this be a performance hog?
for whatever operation you perform on the record you will do a 2-level join to get the tag-slugs & id's from the corresponding tag-map/tag table class.

wouldn't it be better if you could get override the way it is presented? (and do the join when they want to present it?)

so when a user calls {{ form.tags }} in the form it would display the tags as a either a textbox, or as a series of links?

FWIW.. I did the same thing with a change manipulator (as you know) and it kinda works

What I would really like to be able to do is define a model class as 'taggable' and it automatically would create the corresponding tag related functions...maybe overriding the meta.model class is a better idea?

comment:3 Changed 9 years ago by hugo

Sure, allways pulling it in would go on performance, as you would need to do the second select - but the sample was just that, a sample ;-)

In the case of the tags I actually would store a lazy string in the field so that the select is only done when the field is really used as a string value (for example in rendering the form). And then I would need to do the select anyway, as I need the current data.

But the important thing would be the hook, so that I get the chance to actually do something when a new object is constructed. I am not absolutely sure that _post_init would be the right place, though - there might be a better place, more like a _post_select, that is only called when a object is created from real data, as init is called for new objects, too.

comment:4 Changed 9 years ago by ian@…

I guess that was my point, but you worded it better...

if the only need for this post_init hook would be for rendering, would it be better to hang the hook where rendering takes place instead of on the db?
(or just rename it to be pre_render or something).
even then you don't want it be called everytime you view the record (or fields on the record) do you?

comment:5 Changed 9 years ago by hugo

Hmm. There might be different uses than just webapps - for example in batch scripts. So I think the best place would be when some object is read from the database, so that the model can make sure the object is in the right state after reading. In my example I talked about database tables - but in my Gallery for example my objects are just duplicates of data in the filesystem. So it would be handy to check in a _post_select hook for wether the object is still current. In the case of the filesystem I wouldn't need to pull in all stuff, I only need to check change dates.

I just think that it could be helpful to have a hook that's the corresponding hook to the _pre_save hook. That one makes sure an object is in the right state to be stored in the database, while _post_select would make sure that an object is in the right state when read from the database.

comment:6 Changed 8 years ago by jacob

  • Resolution set to invalid
  • Status changed from new to closed

In .92 you can just define init to do what you want. Marking invalid.

Add Comment

Modify Ticket

Change Properties
<Author field>
Action
as closed
as The resolution will be set. Next status will be 'closed'
The resolution will be deleted. Next status will be 'new'
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.