Opened 9 years ago

Closed 9 years ago

Last modified 8 years ago

#905 closed enhancement (wontfix)

[patch] Add _pre_set and _post_set hooks to models

Reported by: andreas@… Owned by: adrian
Component: Core (Other) Version:
Severity: normal Keywords:
Cc: Triage Stage: Unreviewed
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: UI/UX:

Description

"set_thingie" methods for many-to-many related objects (as well as "set_thingie_order" and "get_thingie_order" methods) don't trigger _pre_save or _post_save. I needed these hooks so here's a small patch that adds them.

Index: django/core/meta/__init__.py
===================================================================
--- /home/andreas/workspace/django_src/django/core/meta/__init__.py	(revision 1396)
+++ /home/andreas/workspace/django_src/django/core/meta/__init__.py	(working copy)
@@ -924,6 +960,9 @@
 # Handles setting many-to-many relationships.
 # Example: Poll.set_sites()
 def method_set_many_to_many(rel_field, self, id_list):
+    # Run any pre-set hooks.
+    if hasattr(self, '_pre_set'):
+        self._pre_set()
     current_ids = [obj.id for obj in method_get_many_to_many(rel_field, self)]
     ids_to_add, ids_to_delete = dict([(i, 1) for i in id_list]), []
     for current_id in current_ids:
@@ -956,6 +995,9 @@
         delattr(self, '_%s_cache' % rel_field.name) # clear cache, if it exists
     except AttributeError:
         pass
+    # Run any post-set hooks.
+    if hasattr(self, '_post_set'):
+        self._post_set()
     return True
 
 # Handles related-object retrieval.
@@ -990,6 +1032,9 @@
 # Handles setting many-to-many related objects.
 # Example: Album.set_songs()
 def method_set_related_many_to_many(rel_opts, rel_field, self, id_list):
+    # Run any pre-set hooks.
+    if hasattr(self, '_pre_set'):
+        self._pre_set()
     id_list = map(int, id_list) # normalize to integers
     rel = rel_field.rel.to
     m2m_table = rel_field.get_m2m_db_table(rel_opts)
@@ -1004,6 +1049,9 @@
         db.db.quote_name(rel_opts.object_name.lower() + '_id'))
     cursor.executemany(sql, [(this_id, i) for i in id_list])
     db.db.commit()
+    # Run any post-set hooks.
+    if hasattr(self, '_post_set'):
+        self._post_set()
 
 # ORDERING METHODS #########################
 
@@ -1008,6 +1056,9 @@
 # ORDERING METHODS #########################
 
 def method_set_order(ordered_obj, self, id_list):
+    # Run any pre-set hooks.
+    if hasattr(self, '_pre_set'):
+        self._pre_set()
     cursor = db.db.cursor()
     # Example: "UPDATE poll_choices SET _order = %s WHERE poll_id = %s AND id = %s"
     sql = "UPDATE %s SET %s = %%s WHERE %s = %%s AND %s = %%s" % \
@@ -1017,6 +1068,9 @@
     rel_val = getattr(self, ordered_obj.order_with_respect_to.rel.field_name)
     cursor.executemany(sql, [(i, rel_val, j) for i, j in enumerate(id_list)])
     db.db.commit()
+    # Run any pre-set hooks.
+    if hasattr(self, '_post_set'):
+        self._pre_set()
 
 def method_get_order(ordered_obj, self):
     cursor = db.db.cursor()

The patch is probably not universally useful since you might want to further differentiate between set_order and set_many_to_many.

Change History (2)

comment:1 Changed 9 years ago by andreas@…

Correction: The lines @@ -1017,6 +1068,9 @@

+    # Run any pre-set hooks.
+    if hasattr(self, '_post_set'):
+        self._pre_set()

should of course read

+    # Run any post-set hooks.
+    if hasattr(self, '_post_set'):
+        self._post_set()

comment:2 Changed 9 years ago by jacob

  • Resolution set to wontfix
  • Status changed from new to closed

This is fixed by now allowing properties on magic-removal.

Also, in the future please submit patches that conform to the patch guidlines (http://www.djangoproject.com/documentation/contributing/#patch-style)

Note: See TracTickets for help on using tickets.
Back to Top