Jason L.
unread,Apr 7, 2008, 12:46:40 PM4/7/08Sign in to reply to author
Sign in to forward
You do not have permission to delete messages in this group
Either email addresses are anonymous for this group or you need the view member email addresses permission to view the original message
to django-gsoc
Alberto,
Just a fellow student applicant, but thought I'd chime in.
Your goal, it seems, is to be able to add functionality to a model
without the model needing to be aware of that added functionality.
Most such "uncoupled" extensions are currently done through generic
foreign keys.
To rephrase your example:
class Subscriber(models.Model):
subscriber_model = models.ForeignKey(ContentType)
subscriber_id = models.PositiveIntegerField()
subscriber = generic.GenericForeignKey('content_type',
'object_id')
comment = models.ForeignKey(Comment)
def send_emails(self):
...
This approach in general is a bit awkward and sub-optimal at the
moment and subclassing will do little to "uncouple" a plugin from its
model. Bear in mind, however, that your approach wouldn't uncouple
things either. Users of the given plugin still have to hand-append
their extra functionality in their own code. Everything still has
rigid links.
When you're rigidly coupled, this can create a variety of problems.
First, if the implementation of the model changes on you, your code
breaks. Furthermore, namespace issues can easily arise, where two
plugins add different fields with the same name. Subclassing avoids
this because the model heirarchy garuantees which field you end up
with at a given point in the inheritance tree. Your plugin method,
however, would have an undefined result (the field you end up with
depends on the path of code execution).
Automatically adjusting tables on the back-end is seriously bad mojo.
What if a namespace conflict occurs, and suddenly your table juggler
sees a field, "priority", which was an integer but is now a positive
integer because a new plugin has overridden the old field. Your
juggler will change around the field, potentially destroying whole
swaths of data.
As Malcolm mentioned, signal handlers can be used to tell when an
object is saved (check out the dispatch code in trunk). You'd have to
work a little magic on processing the signals (since you won't know
beforehand what models to watch for, so you can't bind to a complex
signal that includes the model). Rewriting dispatch isn't necessarily
a good idea; dispatch has some neat tricks like a well-written "robust
apply" method for intelligently passing arguments to callbacks.
You could change your approach and instead of writing new
functionality for all of this, you could make convenience functions
that wrap around the current functionality, to make such extensions of
current apps easier to write. I'm not sure if this would constitute
enough work on its own to be a SoC project, however.
Also bear in mind that you're talking about extending django
'applications', not extending Django itself, so your firefox analogy
isn't quite accurate.
It's not a bad idea to want to streamline this process, but doing so
runs pretty deep into the code and involves considerations you haven't
taken into account.
Sorry to be a gloomy gus, hope I've helped some.
-Jason L.