-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Improve Reverse Delete Rules #2765
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
base: master
Are you sure you want to change the base?
Improve Reverse Delete Rules #2765
Conversation
mm i guess its not working : ) will come back to this later. |
f.document_type.register_delete_rule( | ||
new_class, field.name, delete_rule |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the ideal world I would cut out document_type
here and just make fields responsible for implementing register_delete_rule
.
However, when I tried this I realized that it would break the interface for how to register delete rules and thus any users dynamically setting delete rules would be upset.
Use the `reverse_delete_rule` to handle what should happen if the document | ||
the field is referencing is deleted. EmbeddedDocuments, DictFields and | ||
MapFields does not support reverse_delete_rule and an `InvalidDocumentError` | ||
will be raised if trying to set on one of these Document / Field types. | ||
|
||
The options are: | ||
|
||
* DO_NOTHING (0) - don't do anything (default). | ||
* NULLIFY (1) - Updates the reference to null. | ||
* CASCADE (2) - Deletes the documents associated with the reference. | ||
* DENY (3) - Prevent the deletion of the reference object. | ||
* PULL (4) - Pull the reference from a :class:`~mongoengine.fields.ListField` of references | ||
|
||
Alternative syntax for registering delete rules | ||
|
||
.. code-block:: python | ||
|
||
class Org(Document): | ||
owner = ReferenceField('User') | ||
|
||
class User(Document): | ||
org = ReferenceField('Org', reverse_delete_rule=CASCADE) | ||
|
||
User.register_delete_rule(Org, 'owner', DENY) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This wasn't showing up in sphinx when I ran make html-readthedocs
, not sure why?
@@ -1453,8 +1512,11 @@ class GenericReferenceField(BaseField): | |||
* You can use the choices param to limit the acceptable Document types | |||
""" | |||
|
|||
def __init__(self, *args, **kwargs): | |||
def __init__(self, *args, reverse_delete_rule=DO_NOTHING, **kwargs): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would like to call this param out in the GenericReferenceField
docs but I couldn't seem to get it to show up properly, I'd make a docstring for the init but it wouldn't populate to the docs 🤷
@bagerard I know you're busy, anything more I need to do to get this merged in? Fixed a couple issues - just need a bit of help with the sphinx formatting. |
Fixes issues #2764 and #2308, implements lazy delete rules and delete rules on GenericReferenceFields.
To implement lazy delete rules:
When delete rules are assigned to a Document that doesn't exist yet, I store them in a global dict. Whenever a new Document class is defined, it checks said global dict for any outstanding delete rules that it needs to assign on itself.
To implement delete rules on GenericReferenceFields:
GenericReferenceField is now smart enough to register delete rules on many documents when its asked to. It does this by employing a helper class which provides a
register_delete_rule
function that actually can register delete rules on many documents, not just one. It exposes this class by defining adocument_type
property, which is kind of lying in a sense since this really is only intended to exposeregister_delete_rule
and not handle any other functionality expected ofdocument_type
.This is a little janky but I can't think of a way to do it "right" without changing which class is responsible for
register_delete_rule
and thus making a breaking change.