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.