Class based models

6 views
Skip to first unread message

Klaas van Schelven

unread,
Sep 26, 2010, 8:28:35 AM9/26/10
to Django developers
Hi all,

I'm looking for a bit of input for making Django's apps a bit more
extendable, either by modifying Django or (preferably) by coming up
with a common language on top op Django. The main painpoint are
extendable models. The idea of 'extendable' is that models from
reusable apps can be extended in any concrete project. The reusable
apps should refer to their own models in such a way that they will get
the concrete implementation (extension).
Class based models if you will.

Context can be found here:
http://groups.google.com/group/django-users/browse_thread/thread/22875fd287d0aa81/313b7bb67f24ad2f

Currently, apps usually refer to their own models by simply importing
them from models.py and referring to them. This obviously will not
work, so any solution will need some kind of registry, or instance of
"app". If "app" is an instance of a class referring to it can be done
in an extendible way (simply by using Python's inheritance mechanism).

I've put an example of this approach here:
http://bitbucket.org/vanschelven/extendible_app_experiment/src/0862cecb358d

Which incorporates the above idea of an app class & instance in blog/
__init__.py.

abstract_blog/abstract_models.py and blog/models.py

The key sections are:
(in abstract_models)

def get_AbstractPage(self):
class AbstractPage(models.Model):
body = models.TextField()
category = models.ForeignKey(self.app.models.Category)

class Meta:
abstract = True
#app_label = 'abstract_blog'
return AbstractPage
AbstractPage = property(get_AbstractPage)

(in models)
def get_Category(self):
class Category(self.AbstractCategory):
some_added_field = models.IntegerField()
return Category
Category = property(get_Category)

As you can see, it is possible to refer to "the apps real
implementation of Category" (self.app.models.Category, or just
self.Category) from the abstract model. Less neat: the cruft that's
needed to pass self into AbstractPage for reference (3 lines per
class: def, return & property).

In a more recent version I've managed to factor those lines away at
the cost of a lot of magic.
http://bitbucket.org/vanschelven/extendible_app_experiment/src/2b8eb68e8ee5

class AbstractModels(object):
#...
class AbstractPage(shmodels.Model):
body = shmodels.TextField()
category =
shmodels.ForeignKey(Zelf("app.models.Category"))

Neet uh? Self referral without an actual introduction of "self".

I may look for the general case of Zelf & Zelf2 and shmodels and
whatever... but I'd like to know that this is a path worth following.
In other words: am I missing really obvious, more simple solutions
here?

ciao,
Klaas

sub...@gmail.com

unread,
Sep 26, 2010, 10:17:51 PM9/26/10
to Django developers
I may be dense but is this the functional equiv of cobtrib.comments
get_model()?

On Sep 26, 8:28 am, Klaas van Schelven <klaasvanschel...@gmail.com>
wrote:
> Hi all,
>
> I'm looking for a bit of input for making Django's apps a bit more
> extendable, either by modifying Django or (preferably) by coming up
> with a common language on top op Django. The main painpoint are
> extendable models. The idea of 'extendable' is that models from
> reusable apps can be extended in any concrete project. The reusable
> apps should refer to their own models in such a way that they will get
> the concrete implementation (extension).
> Class based models if you will.
>
> Context can be found here:http://groups.google.com/group/django-users/browse_thread/thread/2287...
>
> Currently, apps usually refer to their own models by simply importing
> them from models.py and referring to them. This obviously will not
> work, so any solution will need some kind of registry, or instance of
> "app". If "app" is an instance of a class referring to it can be done
> in an extendible way (simply by using Python's inheritance mechanism).
>
> I've put an example of this approach here:http://bitbucket.org/vanschelven/extendible_app_experiment/src/0862ce...
> the cost of a lot of magic.http://bitbucket.org/vanschelven/extendible_app_experiment/src/2b8eb6...

Klaas van Schelven

unread,
Sep 27, 2010, 6:02:21 AM9/27/10
to Django developers


On Sep 27, 4:17 am, "subs...@gmail.com" <subs...@gmail.com> wrote:
> I may be dense but is this the functional equiv of cobtrib.comments
> get_model()?

Nope.
Rather, it's a way to subclass models that are provided by reusable
apps, and letting the reusable app use the subclassed instance
throughout.

sub...@gmail.com

unread,
Sep 27, 2010, 1:57:47 PM9/27/10
to Django developers
I thought that's what get_model did?

You specify your own comments app and register your own (subclass or
other) model within that function and its used throughout the original
app.

On Sep 27, 3:02 am, Klaas van Schelven <klaasvanschel...@gmail.com>

Klaas van Schelven

unread,
Sep 27, 2010, 5:45:49 PM9/27/10
to Django developers
There's a quite a few things that I don't like about the get_model
approach. I'll focus on one though: contrib.comment's own models do
not respect it.

Consider a customized model for comments (the model MyComment in
my_comments)
so in settings.py we put:
COMMENTS_APP = 'my_comments'

then we do the following:
from django.contrib.comments.models import CommentFlag
flag = CommentFlag()
from django.contrib.comments import get_model
mycomment = get_model().objects.get()
flag.comment = mycomment

Traceback (most recent call last):
File "<console>", line 1, in <module>
File "...django/db/models/fields/related.py", line 318, in __set__
self.field.name, self.field.rel.to._meta.object_name))
ValueError: Cannot assign "<MyComment: MyComment object>":
"CommentFlag.comment" must be a "Comment" instance.

You see the problem? Any help thinking about the solution is much
appreciated.

Klaas

sub...@gmail.com

unread,
Sep 29, 2010, 3:24:59 PM9/29/10
to Django developers
Hmm... I do see what you're saying.

The line in question, however, should respect subclasses. So your
example wouldn't fail in the case of a proper subclass.

I checked out that thread and I saw Russel commented on it and
ironically he mentioned contrib.comments as well.

One thing you say is 'providing abstract models feels really awkward'--
Why?

It seems like you almost want an 'attributes_for' option in the model
Meta options whereby one model can stand-in for another model. Still,
a lot of your proposal seems to rely on a developer's 'best
practices'--aka something akin to contrib.comments' get_model() use in
views and form (which can't be codified with patches, really).

-Steve

PS: One nag I have about get_model() is that is singular. Sure,
contrib.comments happens to only have one extensible but what about
when there's more?

On Sep 27, 5:45 pm, Klaas van Schelven <klaasvanschel...@gmail.com>

Klaas van Schelven

unread,
Oct 6, 2010, 4:07:37 AM10/6/10
to Django developers
Sorry, missed your reply somehow,
>
> The line in question, however, should respect subclasses. So your
> example wouldn't fail in the case of a proper subclass.
>

I've heard this claim before,
But per my example above it doesn't. What am I doing wrong there?
Reply all
Reply to author
Forward
0 new messages