Signal when creating a new relationship?
Is there a way to use django-signals every time a new relationship is created?
Thanks.
Solved.
class **FriendRel**(StructuredRel):
since = DateTimeProperty(default=lambda: datetime.now(pytz.utc))
met = StringProperty()
class Person(StructuredNode):
name = StringProperty()
friends = RelationshipTo('Person', 'FRIEND', model=**FriendRel**)
Nice one. I am interested know how this works?
On 10 Jun 2017 12:43, "Adrián" [email protected] wrote:
Solved.
`class FriendRel(StructuredRel): since = DateTimeProperty(default=lambda: datetime.now(pytz.utc)) met = StringProperty()
class Person(StructuredNode): name = StringProperty() friends = RelationshipTo('Person', 'FRIEND', model=FriendRel)`
— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/robinedwards/django-neomodel/issues/8#issuecomment-307560141, or mute the thread https://github.com/notifications/unsubscribe-auth/AAJ0YchND5rTumEQKneSCgdkVkWP3WUtks5sCoFPgaJpZM4N0Zea .
One solution would be to extend StructuredRel, like that:
class DjangoRel(StructuredRel):
def __init__(self, *args, **kwargs):
super(DjangoRel, self).__init__(*args, **kwargs)
__all_properties__ = ()
@classproperty
def _meta(self):
if hasattr(self.Meta, 'unique_together'):
raise NotImplementedError('unique_together property not supported by neomodel')
opts = Options(self.Meta, app_label=self.Meta.app_label)
opts.contribute_to_class(self.__class__, self.__class__.__name__)
for key, prop in self.__all_properties__:
opts.add_field(DjangoField(prop, key), getattr(prop, 'private', False))
return opts
def pre_save(self):
if getattr(settings, 'NEOMODEL_SIGNALS', True):
self._creating_node = getattr(self, 'id', None) is None
signals.pre_save.send(sender=self.__class__, instance=self)
def post_save(self):
if getattr(settings, 'NEOMODEL_SIGNALS', True):
created = None
#delattr(self, '_creating_node')
signals.post_save.send(sender=self.__class__, instance=self, created=created)
def pre_delete(self):
if getattr(settings, 'NEOMODEL_SIGNALS', True):
signals.pre_delete.send(sender=self.__class__, instance=self)
def post_delete(self):
if getattr(settings, 'NEOMODEL_SIGNALS', True):
signals.post_delete.send(sender=self.__class__, instance=self)
class FriendRel(DjangoRel):
weight = IntegerProperty(default=0)
class Meta:
app_label = 'django_rel'
It may not be an elegant solution, but it works (at least in post_save).
I'm still working, I hope to improve it soon.
I think overwriting the "disconnect" method of "RelationshipManager" can be implemented "disconnect-signal".
Something like that:
in relationship_manager.py:
@check_source
def disconnect(self, node):
"""
Disconnect a node
:param node:
:return:
"""
rel = _rel_helper(lhs='a', rhs='b', ident='r', **self.definition)
q = "MATCH (a), (b) WHERE id(a)={self} and id(b)={them} " \
"MATCH " + rel + " DELETE r"
self.source.cypher(q, {'them': node.id})
signals.post_disconnect.send(sender=None, uid=node.uid, title=node.title)
in signals.py:
from django.dispatch import Signal
post_disconnect = Signal(providing_args=["uid", "title"])
in views.py
def disconnect_handler(sender, **kwargs):
"""signal intercept for post_disconnect"""
uid = kwargs['uid']
...
post_disconnect.connect(disconnect_handler)
Cool I can see how this would be useful.
I guess there is the edge case of disconnect though when a connected node gets deleted? Also how would you handle nodes that were connected or disconnected elsewhere in your code base via a manual cypher query?
On 10 June 2017 at 15:06, Adrián [email protected] wrote:
I think overwriting the "disconnect" method of "RelationshipManager" can be implemented "disconnect-signal".
Something like that:
in relationship_manager.py:
@check_source def disconnect(self, node): """ Disconnect a node :param node: :return: """ rel = _rel_helper(lhs='a', rhs='b', ident='r', **self.definition) q = "MATCH (a), (b) WHERE id(a)={self} and id(b)={them} " \ "MATCH " + rel + " DELETE r" self.source.cypher(q, {'them': node.id}) signals.post_disconnect.send(sender=None, uid=node.uid, title=node.title) **in signals.py:** from django.dispatch import Signal post_disconnect = Signal(providing_args=["uid", "title"]) **in views.py** def disconnect_handler(sender, **kwargs): """signal intercept for post_disconnect""" uid = kwargs['uid'] ... post_disconnect.connect(disconnect_handler) — You are receiving this because you commented. Reply to this email directly, view it on GitHub <https://github.com/robinedwards/django-neomodel/issues/8#issuecomment-307567188>, or mute the thread <https://github.com/notifications/unsubscribe-auth/AAJ0YZT7TVPU2BvKrEd0aryNeMZyEW_rks5sCqLTgaJpZM4N0Zea> .
I think that post_save is called when save() method of RelationRel is called.
connect() method call save()?
Nope the connect() method executes a cypher query under the hood for speed.
On 10 June 2017 at 17:12, Adrián [email protected] wrote:
I think that post_save is called when save() method of RelationRel is called.
connect() method call save()?
— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/robinedwards/django-neomodel/issues/8#issuecomment-307574575, or mute the thread https://github.com/notifications/unsubscribe-auth/AAJ0Ycg3t10jKZvdamFgwRx737JJic9tks5sCsBZgaJpZM4N0Zea .
Uhm... When i "connect" a new relation post_save is called, but, when i "disconnect" pre/post_delete isnt called.
Aha!
I forgot:
https://github.com/robinedwards/neomodel/blob/master/neomodel/relationship_manager.py#L104
I guess for delete to work we need to inflate the model before deleting it which would mean an extra query..
On 10 June 2017 at 17:51, Adrián [email protected] wrote:
Uhm... When i "connect" a new relation post_save is called, but, when i "disconnect" pre/post_delete isnt called.
— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/robinedwards/django-neomodel/issues/8#issuecomment-307576939, or mute the thread https://github.com/notifications/unsubscribe-auth/AAJ0YZ3Lq7GShCCxab-9M4zyecKKV2I4ks5sCsmsgaJpZM4N0Zea .
I think it would be very useful to use signals in the operations (like connect or disconnect) of relationships.
Agreed, as long as the edge cases are well documented.
I guess it should be a specific signal 'connect' and 'disconnect' as we cant piggy back save and delete.
Another thing is there shouldnt be delete signals on StructuredRel as I believe I removed the delete method.. This needs to be more clear in the docs.
Completely agree with you.
Specific signal for 'connect' and 'disconnect' is the best option.
Any progress on this?
@aaronst Unfortunately, I could not have time to do it
@adriancarayol in your pre_save, is id referring to the internal id of the node, or did you explicitly set id = UniqueIdProperty()?
So as I understand it, we can use your DjangoRel class for listeners on creating connections, but deleting connections is still up in the air? thank you for your efforts =)
@laynetrain i refer id to the internal id of the node 👍
I would like to take time out within a few weeks to complete this problem