Re: Fully Polymorphic Django Models: a simple implementation
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 > > a common base class): > > > >>> Base.
Re: Fully Polymorphic Django Models: a simple implementation
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) > > class MyModelWithThirdParty(M
Fully Polymorphic Django Models: a simple implementation
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 = models.ManyToManyField('M