netzkolchose / django-computedfields

Provides autogenerated autoupdated database fields for model methods.
MIT License
94 stars 14 forks source link

handle actions by fk related manager #146

Open jerch opened 9 months ago

jerch commented 9 months ago

Currently many actions of related managers are not properly handled - some work, others dont. Seems the reason for some not working comes from bulk usage internally (all have a bulk=True argument).

Not sure yet, if and how we can get this working for all methods, main issue here is the dynamic creation of the managers and whether we can intercept/overload that somehow. If thats not possible, we should at least put a warning in the docs.

This is also linked to proper M2M handling, as it is done similar by django (but other than fk related manager actions, M2M actions are currently covered by signal handlers in CF). If we find a better way to deal with the mass actions from related managers in general we prolly should revisit the M2M handlers as well.

Ref: https://docs.djangoproject.com/en/5.0/ref/models/relations/

jerch commented 9 months ago

For ref (dont like yet, where this leads) - quick&dirty test to get a hold of the related manager creation:

    def _patch_fks(self) -> None:
        from django.utils.functional import cached_property
        from django.db.models.fields.related_descriptors import create_reverse_many_to_one_manager

        def injected(self):
            related_model = self.rel.related_model
            print('--------------- injected! ------------------')
            return create_reverse_many_to_one_manager(
                related_model._default_manager.__class__,
                self.rel,
            )

        if self.get_contributing_fks():
            from django.db.models.fields.related_descriptors import ReverseManyToOneDescriptor
            ReverseManyToOneDescriptor.related_manager_cls = cached_property(injected)
            ReverseManyToOneDescriptor.related_manager_cls.__set_name__(ReverseManyToOneDescriptor, 'related_manager_cls')

With this it is possible to provide our own create_reverse_many_to_one_manager impl returning a custom RelatedManager with cf update logic for contributing fk fields even in the bulk case.

But before going down the monkey patching rabbit hole, there are several things to clarify: