summaryrefslogtreecommitdiff
path: root/postgresqleu/util/diffablemodel.py
diff options
context:
space:
mode:
authorMagnus Hagander2015-08-27 10:23:39 +0000
committerMagnus Hagander2015-08-31 20:16:38 +0000
commit84645d071f4918bb36c9e85f5e6516e92fd2418a (patch)
tree2f3c2f48a6a6e89f92160a2acf02bc8d9ca99af7 /postgresqleu/util/diffablemodel.py
parent8f8085c91615bc536ede48306643ae76cb5ee7df (diff)
Implement basic conference wiki support
This is a limited wiki for conference attendees, intended for things like ride sharing or restaurant coordination. The wiki supports simple markdown syntax, and nothing more than that. Only admins can create pages (through the dashboard). Each page can be assigned permissions (public, based on regtype, or individual attendee) to view and/or edit the pages. *Only* confirmed registrations will ever be able to see anything on the wiki (unlike previous times when we've used public pages on the main postgresql.org wiki). If at least one page is visible to the attendee, the section shows up on the registration dashboard. Attendees can subscribe to changes to a page, in which case they will receive an email when the page is edited. Changes are always sent to the conference contact address (for post-moderation if required). History is tracked on all pages, and it's possible to view the history of a page including diff between versions (unless disabled on individual wiki pages from the admin interface). To implement the diff functionality, import the diffablemodel code from the pgcommitfest app that does similar things, and build on top of that.
Diffstat (limited to 'postgresqleu/util/diffablemodel.py')
-rw-r--r--postgresqleu/util/diffablemodel.py43
1 files changed, 43 insertions, 0 deletions
diff --git a/postgresqleu/util/diffablemodel.py b/postgresqleu/util/diffablemodel.py
new file mode 100644
index 00000000..7a38c7b0
--- /dev/null
+++ b/postgresqleu/util/diffablemodel.py
@@ -0,0 +1,43 @@
+from django.forms.models import model_to_dict
+import django.db.models.fields.related
+
+
+class DiffableModel(object):
+ """
+ Make it possible to diff a model.
+ """
+
+ def __init__(self, *args, **kwargs):
+ super(DiffableModel, self).__init__(*args, **kwargs)
+ self.__initial = self._dict
+
+ @property
+ def diff(self):
+ manytomanyfieldnames = [f.name for f in self._meta.many_to_many]
+ d1 = self.__initial
+ d2 = self._dict
+ diffs = dict([(k, (v, d2[k])) for k, v in d1.items() if v != d2[k]])
+ # Foreign key lookups
+ for k,v in diffs.items():
+ if type(self._meta.get_field_by_name(k)[0]) is django.db.models.fields.related.ForeignKey:
+ # If it's a foreign key, look up the name again on ourselves.
+ # Since we only care about the *new* value, it's easy enough.
+ diffs[k] = (v[0], getattr(self, k))
+ # Many to many lookups
+ if hasattr(self, 'map_manytomany_for_diff'):
+ for k,v in diffs.items():
+ if k in manytomanyfieldnames and self.map_manytomany_for_diff.has_key(k):
+ # Try to show the display name instead here
+ newvalue = getattr(self, self.map_manytomany_for_diff[k])
+ diffs[k] = (v[0], newvalue)
+ return diffs
+
+ def save(self, *args, **kwargs):
+ super(DiffableModel, self).save(*args, **kwargs)
+ self.__initial = self._dict
+
+ @property
+ def _dict(self):
+ fields = [field.name for field in self._meta.fields]
+ fields.extend([field.name for field in self._meta.many_to_many])
+ return model_to_dict(self, fields=fields)