Re: Fully Polymorphic Django Models: a simple implementation

2010-01-22 Thread hejsan
This is the best news I've heard for a long time!

This was also my biggest disappointment with Django. This bit me in my
first django project, which incidentally was also my first experience
with ORM.

Basically I had the following class structure:

Project
 Art Project
 Research Project
 Lecture
...
And I wanted to allow the projects to link each other for a "Related
projects" feature... i figured it would be easy, just:
Project.objects.all()...but no, impossible.
Then I figured out that ORM != OO

This elementary feature should be merged into the basic django Model
class IMO.

On Jan 22, 1:00 pm, rvdrijst  wrote:
> Wow, amazing job!
>
> This addresses the big disappointment I felt when I found out django
> Model Inheritance didn't do this by default. I used some ugly
> workarounds to make it happen and this seems like the perfect
> solution. Main problem is that it requires django 1.1, I'm working
> with trunk/1.2, but I'm going to give it a try anyway.
>
> I'll keep tracking the developments on github, keep up the good work!
>
> - Robin
>
> On Jan 15, 8:55 pm, Bert Constantin  wrote:
>
> > Hello everyone!
>
> > I just uploaded a simple but mostly complete implementation of model
> > and queryset polymorphism onto github and bitbucket.
>
> > For enabled models, this implementation simply makes all references
> > to the model's objects polymorphic (be it managers/querysets or
> > relationship fields).
>
> > The prototype might be useful as a tool for concretely exploring the
> > concept of polymorphic models within the Django framework (and
> > perhaps might find use in real projects as well).
>
> > My impression is that fully polymorphic models and querysets
> > integrate very well into the Django ORM and database API. Also, with
> > Django's ORM and model inheritance system, all the heavy lifting
> > has already been done; only a rather thin layer above seems
> > to be required to get to a complete implementation of polymorphic
> > inheritance.
>
> > Below I copied the docstring of the module.
> > Near the top are a number of short examples that are good as a quick
> > overview.
>
> > The docstring can be read in a much better format 
> > here:http://bserve.webhop.org/wiki/django_polymorphic
>
> > Suggestions and criticism are very welcome.
>
> > Kind Regards,
> > Bert Constantin
>
> > GitHub:http://github.com/bconstantin/django_polymorphic
> > Bitbucket:http://bitbucket.org/bconstantin/django_polymorphic
> > Tar:http://github.com/bconstantin/django_polymorphic/tarball/master
>
> > +++
>
> > Defining Polymorphic Models
> > ===
>
> > To make models polymorphic, use PolymorphicModel instead of Django's
> > models.Model as the superclass of your base model. All models
> > inheriting from your base class will be polymorphic as well::
>
> >     from polymorphic import PolymorphicModel
>
> >     class ModelA(PolymorphicModel):
> >         field1 = models.CharField(max_length=10)
>
> >     class ModelB(ModelA):
> >         field2 = models.CharField(max_length=10)
>
> >     class ModelC(ModelB):
> >         field3 = models.CharField(max_length=10)
>
> > Using Polymorphic Models
> > 
>
> > Most of Django's standard ORM functionality is available
> > and works as expected:
>
> > Create some objects
> > ---
>
> >     >>> ModelA.objects.create(field1='A1')
> >     >>> ModelB.objects.create(field1='B1', field2='B2')
> >     >>> ModelC.objects.create(field1='C1', field2='C2', field3='C3')
>
> > Query results are polymorphic
> > -
>
> >     >>> ModelA.objects.all()
> >     .
> >     [ ,
> >       ,
> >        > (CharField)> ]
>
> > Filtering for classes (equivalent to python's isinstance() ):
> > -
>
> >     >>> ModelA.objects.instance_of(ModelB)
> >     .
> >     [ ,
> >        > (CharField)> ]
>
> >     In general, including or excluding parts of the inheritance tree::
>
> >         ModelA.objects.instance_of(ModelB [, ModelC ...])
> >         ModelA.objects.not_instance_of(ModelB [, ModelC ...])
>
> > Polymorphic filtering (for fields in derived classes)
> > -
>
> >     For example, cherrypicking objects from multiple derived classes
> >     anywhere in the inheritance tree, using Q objects (with the
> >     slightly enhanced syntax: exact model name + three _ + field
> > name):
>
> >     >>> ModelA.objects.filter(  Q( ModelB___field2 = 'B2' )  |  Q
> > ( ModelC___field3 = 'C3' )  )
> >     .
> >     [ ,
> >        > (CharField)> ]
>
> > Combining Querysets of different types/models
> > -
>
> >     Querysets may now be regarded as object containers that allow the
> >     aggregation of  different object types - very similar to python
> >     lists (as long as the objects are accessed through the manager of
> >  

Re: Fully Polymorphic Django Models: a simple implementation

2010-01-22 Thread rvdrijst
Wow, amazing job!

This addresses the big disappointment I felt when I found out django
Model Inheritance didn't do this by default. I used some ugly
workarounds to make it happen and this seems like the perfect
solution. Main problem is that it requires django 1.1, I'm working
with trunk/1.2, but I'm going to give it a try anyway.

I'll keep tracking the developments on github, keep up the good work!

- Robin

On Jan 15, 8:55 pm, Bert Constantin  wrote:
> Hello everyone!
>
> I just uploaded a simple but mostly complete implementation of model
> and queryset polymorphism onto github and bitbucket.
>
> For enabled models, this implementation simply makes all references
> to the model's objects polymorphic (be it managers/querysets or
> relationship fields).
>
> The prototype might be useful as a tool for concretely exploring the
> concept of polymorphic models within the Django framework (and
> perhaps might find use in real projects as well).
>
> My impression is that fully polymorphic models and querysets
> integrate very well into the Django ORM and database API. Also, with
> Django's ORM and model inheritance system, all the heavy lifting
> has already been done; only a rather thin layer above seems
> to be required to get to a complete implementation of polymorphic
> inheritance.
>
> Below I copied the docstring of the module.
> Near the top are a number of short examples that are good as a quick
> overview.
>
> The docstring can be read in a much better format 
> here:http://bserve.webhop.org/wiki/django_polymorphic
>
> Suggestions and criticism are very welcome.
>
> Kind Regards,
> Bert Constantin
>
> GitHub:http://github.com/bconstantin/django_polymorphic
> Bitbucket:http://bitbucket.org/bconstantin/django_polymorphic
> Tar:http://github.com/bconstantin/django_polymorphic/tarball/master
>
> +++
>
> Defining Polymorphic Models
> ===
>
> To make models polymorphic, use PolymorphicModel instead of Django's
> models.Model as the superclass of your base model. All models
> inheriting from your base class will be polymorphic as well::
>
>     from polymorphic import PolymorphicModel
>
>     class ModelA(PolymorphicModel):
>         field1 = models.CharField(max_length=10)
>
>     class ModelB(ModelA):
>         field2 = models.CharField(max_length=10)
>
>     class ModelC(ModelB):
>         field3 = models.CharField(max_length=10)
>
> Using Polymorphic Models
> 
>
> Most of Django's standard ORM functionality is available
> and works as expected:
>
> Create some objects
> ---
>
>     >>> ModelA.objects.create(field1='A1')
>     >>> ModelB.objects.create(field1='B1', field2='B2')
>     >>> ModelC.objects.create(field1='C1', field2='C2', field3='C3')
>
> Query results are polymorphic
> -
>
>     >>> ModelA.objects.all()
>     .
>     [ ,
>       ,
>        (CharField)> ]
>
> Filtering for classes (equivalent to python's isinstance() ):
> -
>
>     >>> ModelA.objects.instance_of(ModelB)
>     .
>     [ ,
>        (CharField)> ]
>
>     In general, including or excluding parts of the inheritance tree::
>
>         ModelA.objects.instance_of(ModelB [, ModelC ...])
>         ModelA.objects.not_instance_of(ModelB [, ModelC ...])
>
> Polymorphic filtering (for fields in derived classes)
> -
>
>     For example, cherrypicking objects from multiple derived classes
>     anywhere in the inheritance tree, using Q objects (with the
>     slightly enhanced syntax: exact model name + three _ + field
> name):
>
>     >>> ModelA.objects.filter(  Q( ModelB___field2 = 'B2' )  |  Q
> ( ModelC___field3 = 'C3' )  )
>     .
>     [ ,
>        (CharField)> ]
>
> Combining Querysets of different types/models
> -
>
>     Querysets may now be regarded as object containers that allow the
>     aggregation of  different object types - very similar to python
>     lists (as long as the objects are accessed through the manager of
>     a common base class):
>
>     >>> Base.objects.instance_of(ModelX) | Base.objects.instance_of
> (ModelY)
>     .
>     [ ,
>        ]
>
> Using Third Party Models (without modifying them)
> -
>
>     Third party models can be used as polymorphic models without any
>     restrictions by simply subclassing them. E.g. using a third party
>     model as the root of a polymorphic inheritance tree::
>
>         from thirdparty import ThirdPartyModel
>
>         class MyThirdPartyModel(PolymorhpicModel, ThirdPartyModel):
>             pass    # or add fields
>
>     Or instead integrating the third party model anywhere into an
>     existing polymorphic inheritance tree::
>
>         class MyModel(SomePolymorphicModel):
>             my_field = models.CharField(max_length=10)
>
>         

Fully Polymorphic Django Models: a simple implementation

2010-01-15 Thread Bert Constantin
Hello everyone!

I just uploaded a simple but mostly complete implementation of model
and queryset polymorphism onto github and bitbucket.

For enabled models, this implementation simply makes all references
to the model's objects polymorphic (be it managers/querysets or
relationship fields).

The prototype might be useful as a tool for concretely exploring the
concept of polymorphic models within the Django framework (and
perhaps might find use in real projects as well).

My impression is that fully polymorphic models and querysets
integrate very well into the Django ORM and database API. Also, with
Django's ORM and model inheritance system, all the heavy lifting
has already been done; only a rather thin layer above seems
to be required to get to a complete implementation of polymorphic
inheritance.

Below I copied the docstring of the module.
Near the top are a number of short examples that are good as a quick
overview.

The docstring can be read in a much better format here:
http://bserve.webhop.org/wiki/django_polymorphic

Suggestions and criticism are very welcome.

Kind Regards,
Bert Constantin

GitHub: http://github.com/bconstantin/django_polymorphic
Bitbucket: http://bitbucket.org/bconstantin/django_polymorphic
Tar: http://github.com/bconstantin/django_polymorphic/tarball/master

+++

Defining Polymorphic Models
===

To make models polymorphic, use PolymorphicModel instead of Django's
models.Model as the superclass of your base model. All models
inheriting from your base class will be polymorphic as well::

from polymorphic import PolymorphicModel

class ModelA(PolymorphicModel):
field1 = models.CharField(max_length=10)

class ModelB(ModelA):
field2 = models.CharField(max_length=10)

class ModelC(ModelB):
field3 = models.CharField(max_length=10)


Using Polymorphic Models


Most of Django's standard ORM functionality is available
and works as expected:

Create some objects
---

>>> ModelA.objects.create(field1='A1')
>>> ModelB.objects.create(field1='B1', field2='B2')
>>> ModelC.objects.create(field1='C1', field2='C2', field3='C3')

Query results are polymorphic
-

>>> ModelA.objects.all()
.
[ ,
  ,
   ]

Filtering for classes (equivalent to python's isinstance() ):
-

>>> ModelA.objects.instance_of(ModelB)
.
[ ,
   ]

In general, including or excluding parts of the inheritance tree::

ModelA.objects.instance_of(ModelB [, ModelC ...])
ModelA.objects.not_instance_of(ModelB [, ModelC ...])

Polymorphic filtering (for fields in derived classes)
-

For example, cherrypicking objects from multiple derived classes
anywhere in the inheritance tree, using Q objects (with the
slightly enhanced syntax: exact model name + three _ + field
name):

>>> ModelA.objects.filter(  Q( ModelB___field2 = 'B2' )  |  Q
( ModelC___field3 = 'C3' )  )
.
[ ,
   ]

Combining Querysets of different types/models
-

Querysets may now be regarded as object containers that allow the
aggregation of  different object types - very similar to python
lists (as long as the objects are accessed through the manager of
a common base class):

>>> Base.objects.instance_of(ModelX) | Base.objects.instance_of
(ModelY)
.
[ ,
   ]

Using Third Party Models (without modifying them)
-

Third party models can be used as polymorphic models without any
restrictions by simply subclassing them. E.g. using a third party
model as the root of a polymorphic inheritance tree::

from thirdparty import ThirdPartyModel

class MyThirdPartyModel(PolymorhpicModel, ThirdPartyModel):
pass# or add fields

Or instead integrating the third party model anywhere into an
existing polymorphic inheritance tree::

class MyModel(SomePolymorphicModel):
my_field = models.CharField(max_length=10)

class MyModelWithThirdParty(MyModel, ThirdPartyModel):
pass# or add fields

ManyToManyField, ForeignKey, OneToOneField
--

Relationship fields referring to polymorphic models work as
expected: like polymorphic querysets they now always return the
referred objects with the same type/class these were created and
saved as.

E.g., if in your model you define::

field1 = OneToOneField(ModelA)

then field1 may now also refer to objects of type ModelB or
ModelC.

A ManyToManyField example::

# The model holding the relation may be any kind of model,
polymorphic or not
class RelatingModel(models.Model):
many2many =