Returns the delta (set, unset) of the changes for a document. Gets any values that have been explicitly changed.
(self)
| 686 | return changed_fields |
| 687 | |
| 688 | def _delta(self): |
| 689 | """Returns the delta (set, unset) of the changes for a document. |
| 690 | Gets any values that have been explicitly changed. |
| 691 | """ |
| 692 | # Handles cases where not loaded from_son but has _id |
| 693 | doc = self.to_mongo() |
| 694 | |
| 695 | set_fields = self._get_changed_fields() |
| 696 | unset_data = {} |
| 697 | if hasattr(self, "_changed_fields"): |
| 698 | set_data = {} |
| 699 | # Fetch each set item from its path |
| 700 | for path in set_fields: |
| 701 | parts = path.split(".") |
| 702 | d = doc |
| 703 | new_path = [] |
| 704 | for p in parts: |
| 705 | if isinstance(d, (ObjectId, DBRef)): |
| 706 | # Don't dig in the references |
| 707 | break |
| 708 | elif isinstance(d, list) and p.isdigit(): |
| 709 | # An item of a list (identified by its index) is updated |
| 710 | d = d[int(p)] |
| 711 | elif hasattr(d, "get"): |
| 712 | # dict-like (dict, embedded document) |
| 713 | d = d.get(p) |
| 714 | new_path.append(p) |
| 715 | path = ".".join(new_path) |
| 716 | set_data[path] = d |
| 717 | else: |
| 718 | set_data = doc |
| 719 | if "_id" in set_data: |
| 720 | del set_data["_id"] |
| 721 | |
| 722 | # Determine if any changed items were actually unset. |
| 723 | for path, value in list(set_data.items()): |
| 724 | if value or isinstance( |
| 725 | value, (numbers.Number, bool) |
| 726 | ): # Account for 0 and True that are truthy |
| 727 | continue |
| 728 | |
| 729 | parts = path.split(".") |
| 730 | |
| 731 | if self._dynamic and len(parts) and parts[0] in self._dynamic_fields: |
| 732 | del set_data[path] |
| 733 | unset_data[path] = 1 |
| 734 | continue |
| 735 | |
| 736 | # If we've set a value that ain't the default value don't unset it. |
| 737 | default = None |
| 738 | if path in self._fields: |
| 739 | default = self._fields[path].default |
| 740 | else: # Perform a full lookup for lists / embedded lookups |
| 741 | d = self |
| 742 | db_field_name = parts.pop() |
| 743 | for p in parts: |
| 744 | if isinstance(d, list) and p.isdigit(): |
| 745 | d = d[int(p)] |