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 django-users+unsubscr...@googlegroups.com.
To post to this group, send email to django-users@googlegroups.com.
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