Hello,

I'm having a hard time figuring out both from docs and code what the best 
strategy is 
for preventing a loop, if in post_save() you need to save the provided instance.

I'm implementing an ImageField that is able to handle multiple arbitrary 
thumbnail 
images.

For that purpose I've registered a signal, analog to what ImageField is doing, 
but using 
the post_save signal as I need to have the already saved original available:

*def contribute_to_class(*self, cls, name, ****kwargs*):    
/super/()*.contribute_to_class*(*cls, name, ****kwargs*)    */# noinspection 
PyProtectedMember    /*if not *cls._meta.abstract*:        
*signals.pre_save.connect*(            
*self.generate_thumbs, sender*=*cls,        *)*

The idea was to have the available thumbnails and their url and path stored in 
a 
PostgreSQL Hstore field. For that to work, I need to save the model again, 
hence the 
loop.

To test how to prevent the loop using dispatch_uid, I've created a small test 
app. The 
model uses a HashedTextField:

*class HashedTextField(*TextField*):    def __init__(*self, hash_fieldname, 
***args, 
****kwargs*):        *self.hash_fieldname *= *hash_fieldname        
*/super/(*HashedTextField, self*)*./__init__/*(**args, ****kwargs*)

    def contribute_to_class(*self, cls, name, ****kwargs*):        
/super/(*HashedTextField, self*)*.contribute_to_class*(*cls, name, ****kwargs*) 
       
*post_save.connect*(*self.hash_field, sender*=*cls*)

    def hash_field(*self, instance, ***args, ****kwargs*):        *value *= 
/getattr/(*instance, self.name*)  */# type: *str        */ctx *= 
*Hash*('ripemd160')  */# 
type: HashDescriptor        /ctx.update*(*value*)        /setattr/(*instance, 
self.hash_fieldname, ctx.hexdigest*())        
*instance.save*(*update_fields*=*[self.hash_fieldname]*)

    **def deconstruct(*self*):        *name, path, args, kwargs *= 
/super/(*HashedTextField, self*)*.deconstruct*()        
*kwargs[*'hash_fieldname'*] *= 
*self.hash_fieldname        *return *name, path, args, kwargs


(Hash and HashDescriptor are simple wrappers around hashlib, provided below sig 
for 
the interested).

I've tried:
* dispatch_uid in above contribute_to_class, either with a static string or 
dymically 
generated
* the same but then in __init__() (no diff, as __init__() is called when field 
is attached to 
model, not when an instance is created).

I can either use a different approach (save the hash as a ManyToMany) or use 
something like this on the model:

*def __init__(*self, ***args, ****kwargs*):    *self._saving_hash *= False    
/super/()*./__init__/*(**args, ****kwargs*)*

and then update _saving_hash within hash_field(), which is less then ideal as 
it 
requires the consuming model to alter it's __init__().

Am I missing an option to do this with dispatch_uid from within the field?

-- 
Melvyn Sopacua

/# noinspection PyUnresolvedReferences

/*class HashDescriptor(/object/):    def update(*self, data, encode*=True**):   
     if 
*encode*:            *self._ctx.update*(*data.encode*())        else:           
 
*self._ctx.update*(*data*)

    def hexdigest(*self*):        return *self._ctx.hexdigest*()



class Hash(*HashDescriptor*):    *_ctx *= None

    def __init__(*self, name*):        if *name *in 
*hashlib.algorithms_available*:            
*self._ctx *= *hashlib.new*(*name*)        else:            *self._ctx *= 
*hashlib.sha256*()        
/super/(*Hash, self*)*./__init__/*()



*

-- 
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at https://groups.google.com/group/django-users.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-users/1575417.0Wn4gojWEO%40devstation.
For more options, visit https://groups.google.com/d/optout.

Reply via email to