def annotate(**kwargs): def wrap(func): for name, value in kwargs.iteritems(): # We're annotating, and annotating doesn't mean # overwriting/redegining existing attributes. # # We wouldn't need this assertion if the function were set_attrs. assert not hasattr(func, name) setattr(func, name, value) return func return wrap class MyModel(models.Model): foo = models.CharField(...) bar = models.CharField(...) # OLD: def foobar(self): return '%s' % (self.foo, self.bar) foobar.short_description = 'Returns the foobar' foobar.allow_tags = True # NEW: @annotate(short_description='Returns the foobar', allow_tags=True) def foobar(self): return '%s' % (self.foo, self.bar)