diff --git a/CHANGES.html b/CHANGES.html deleted file mode 100644 index 9eaf216..0000000 --- a/CHANGES.html +++ /dev/null @@ -1,524 +0,0 @@ - - - -
- - -Beta 2 accumulated somewhat more changes than intended, and also -has been delayed by DBMS benchmark testing I wanted to do on model -inheritance. These benchmarks show that there are considerable -problems with concrete model inheritance and contemporary DBM systems. -The results will be forthcoming on the google discussion forum.
-Please also see: -http://www.jacobian.org/writing/concrete-inheritance/
-The API should be stable now with Beta 2, so it's just about potential -bugfixes from now on regarding V1.0.
-Beta 2 is still intended for testing and development environments and not -for production. No complaints have been heard regarding Beta 1 however, -and Beta 1 is used on a few production sites by some enterprising users.
-There will be a release candidate for V1.0 in the very near future.
-API CHANGE: .extra() has been re-implemented. Now it's polymorphic by -default and works (nearly) without restrictions (please see docs). This is a (very) -incompatible API change regarding previous versions of django_polymorphic. -Support for the polymorphic keyword parameter has been removed. -You can get back the non-polymorphic behaviour by using -ModelA.objects.non_polymorphic().extra(...).
-API CHANGE: ShowFieldContent and ShowFieldTypeAndContent now -use a slightly different output format. If this causes too much trouble for -your test cases, you can get the old behaviour back (mostly) by adding -polymorphic_showfield_old_format = True to your model definitions. -ShowField... now also produces more informative output for custom -primary keys.
-.non_polymorphic() queryset member function added. This is preferable to -using .base_objects..., as it just makes the resulting queryset non-polymorphic -and does not change anything else in the behaviour of the manager used (while -.base_objects is just a different manager).
-.get_real_instances(): implementation modified to allow the following -more simple and intuitive use:
-->>> qs = ModelA.objects.all().non_polymorphic() ->>> qs.get_real_instances() --
which is equivalent to:
-->>> ModelA.objects.all() --
added member function: -normal_q_object = ModelA.translate_polymorphic_Q_object(enhanced_q_object)
-misc changes/improvements
-This release is mostly a cleanup and maintenance release that also -improves a number of minor things and fixes one (non-critical) bug.
-Some pending API changes and corrections have been folded into this release -in order to make the upcoming V1.0 API as stable as possible.
-This release is also about getting feedback from you in case you don't -approve of any of these changes or would like to get additional -API fixes into V1.0.
-The release contains a considerable amount of changes in some of the more -critical parts of the software. It's intended for testing and development -environments and not for production environments. For these, it's best to -wait a few weeks for the proper V1.0 release, to allow some time for any -potential problems to show up (if they exist).
-If you encounter any such problems, please post them in the discussion group -or open an issue on GitHub or BitBucket (or send me an email).
-There also have been a number of minor API changes. -Please see the README for more information.
-official Django 1.3 alpha compatibility
-PolymorphicModel.__getattribute__ hack removed. -This improves performance considerably as python's __getattribute__ -generally causes a pretty large processing overhead. It's gone now.
-the polymorphic_dumpdata management command is not needed anymore -and has been disabled, as the regular Django dumpdata command now automatically -works correctly with polymorphic models (for all supported versions of Django).
-.get_real_instances() has been elevated to an official part of the API:
--real_objects = ModelA.objects.get_real_instances(base_objects_list_or_queryset) --
allows you to turn a queryset or list of base objects into a list of the real instances. -This is useful if e.g. you use ModelA.base_objects.extra(...) and then want to -transform the result to its polymorphic equivalent.
-translate_polymorphic_Q_object (see DOCS)
-improved testing
-Changelog added: CHANGES.rst/html
-polymorphic_dumpdata
-The management command polymorphic_dumpdata is not needed anymore -and has been disabled, as the regular Django dumpdata command now automatically -works correctly with polymorphic models (for all supported versions of Django).
-Output of Queryset or Object Printing
-In order to improve compatibility with vanilla Django, printing quersets -(__repr__ and __unicode__) does not use django_polymorphic's pretty printing -by default anymore. To get the old behaviour when printing querysets, -you need to replace your model definition:
-->>> class Project(PolymorphicModel): --
by:
-->>> class Project(PolymorphicModel, ShowFieldType): --
The mixin classes for pretty output have been renamed:
--ShowFieldTypes, ShowFields, ShowFieldsAndTypes-
are now:
--ShowFieldType, ShowFieldContent and ShowFieldTypeAndContent-
(the old ones still exist for compatibility)
-Running the Test suite with Django 1.3
-Django 1.3 requires python manage.py test polymorphic instead of -just python manage.py test.
-IMPORTANT: API Changed (import path changed), and Installation Note
-The django_polymorphic source code has been restructured -and as a result needs to be installed like a normal Django App -- either via copying the "polymorphic" directory into your -Django project or by running setup.py. Adding 'polymorphic' -to INSTALLED_APPS in settings.py is still optional, however.
-The file polymorphic.py cannot be used as a standalone -extension module anymore, as is has been split into a number -of smaller files.
-Importing works slightly different now: All relevant symbols are -imported directly from 'polymorphic' instead from -'polymorphic.models':
--# new way -from polymorphic import PolymorphicModel, ... - -# old way, doesn't work anymore -from polymorphic.models import PolymorphicModel, ... --
Python 2.4 compatibility, contributed by Charles Leifer. Thanks!
-Fix: The exception "...has no attribute 'sub_and_superclass_dict'" -could be raised. (This occurred if a subclass defined __init__ -and accessed class members before calling the superclass __init__). -Thanks to Mattias Brändström.
-Fix: There could be name conflicts if -field_name == model_name.lower() or similar. -Now it is possible to give a field the same name as the class -(like with normal Django models). -(Found through the example provided by Mattias Brändström)
-queryset order_by method added
-queryset aggregate() and extra() methods implemented
-queryset annotate() method implemented
-queryset values(), values_list(), distinct() documented; defer(), -only() allowed (but not yet supported)
-setup.py added. Thanks to Andrew Ingram.
-More about these additions in the docs: -http://bserve.webhop.org/wiki/django_polymorphic/doc
-Fixed ContentType related field accessor clash (an error emitted -by model validation) by adding related_name to the ContentType -ForeignKey. This happened if your polymorphc model used a ContentType -ForeignKey. Thanks to Andrew Ingram.
-Restructured django_polymorphic into a regular Django add-on -application. This is needed for the management commands, and -also seems to be a generally good idea for future enhancements -as well (and it makes sure the tests are always included).
-The poly app - until now being used for test purposes only -- has been renamed to polymorphic. See DOCS.rst -("installation/testing") for more info.
-Added the polymorphic_dumpdata management command (github issue 4), -for creating fixtures, this should be used instead of -the normal Django dumpdata command. -Thanks to Charles Leifer.
-Important: Using ContentType together with dumpdata generally -needs Django 1.2 (important as any polymorphic model uses -ContentType).
-IMPORTANT - database schema change (more info in change log). -I hope I got this change in early enough before anyone started -to use polymorphic.py in earnest. Sorry for any inconvenience. -This should be the final DB schema now.
-Django's ContentType is now used instead of app-label and model-name -This is a cleaner and more efficient solution -Thanks to Ilya Semenov for the suggestion.
-After uncompressing (if necessary), in the directory "...django_polymorphic", -execute (on Unix-like systems):
--sudo python setup.py install --
Use PolymorphicModel instead of Django's models.Model, like so:
--from polymorphic import PolymorphicModel - -class Project(PolymorphicModel): - topic = models.CharField(max_length=30) - -class ArtProject(Project): - artist = models.CharField(max_length=30) - -class ResearchProject(Project): - supervisor = models.CharField(max_length=30) --
All models inheriting from your polymorphic models will be polymorphic as well.
-->>> Project.objects.create(topic="Department Party") ->>> ArtProject.objects.create(topic="Painting with Tim", artist="T. Turner") ->>> ResearchProject.objects.create(topic="Swallow Aerodynamics", supervisor="Dr. Winter") --
->>> Project.objects.all() -[ <Project: id 1, topic "Department Party">, - <ArtProject: id 2, topic "Painting with Tim", artist "T. Turner">, - <ResearchProject: id 3, topic "Swallow Aerodynamics", supervisor "Dr. Winter"> ] --
use instance_of or not_instance_of for narrowing the result to specific subtypes:
-->>> Project.objects.instance_of(ArtProject) -[ <ArtProject: id 2, topic "Painting with Tim", artist "T. Turner"> ] --
->>> Project.objects.instance_of(ArtProject) | Project.objects.instance_of(ResearchProject) -[ <ArtProject: id 2, topic "Painting with Tim", artist "T. Turner">, - <ResearchProject: id 3, topic "Swallow Aerodynamics", supervisor "Dr. Winter"> ] --
Polymorphic filtering: Get all projects where Mr. Turner is involved as an artist -or supervisor (note the three underscores):
-->>> Project.objects.filter( Q(ArtProject___artist = 'T. Turner') | Q(ResearchProject___supervisor = 'T. Turner') ) -[ <ArtProject: id 2, topic "Painting with Tim", artist "T. Turner">, - <ResearchProject: id 4, topic "Color Use in Late Cubism", supervisor "T. Turner"> ] --
This is basically all you need to know, as django_polymorphic mostly -works fully automatic and just delivers the expected ("pythonic") results.
-Note: In all example output, above and below, for a nicer and more informative -output the ShowFieldType mixin has been used (documented below).
-Django 1.1 (or later) and Python 2.4 or later. This code has been tested -on Django 1.1 / 1.2 / 1.3 and Python 2.4.6 / 2.5.4 / 2.6.4 on Linux.
-The repository (or tar file) contains a complete Django project -that may be used for tests or experiments, without any installation needed.
-To run the included test suite, in the directory "...django_polymorphic" execute:
--./manage test polymorphic --
The management command pcmd.py in the app pexp can be used -for quick tests or experiments - modify this file (pexp/management/commands/pcmd.py) -to your liking, then run:
--./manage syncdb # db is created in /var/tmp/... (settings.py) -./manage pcmd --
In the directory "...django_polymorphic", execute sudo python setup.py install.
-Alternatively you can simply copy the polymorphic subdirectory -(under "django_polymorphic") into your Django project dir -(e.g. if you want to distribute your project with more 'batteries included').
-If you want to run the test cases in polymorphic/tests.py, you need to add -polymorphic to your INSTALLED_APPS setting.
-Django's ContentType framework (django.contrib.contenttypes) -needs to be listed in INSTALLED_APPS (usually it already is).
-In the examples below, these models are being used:
--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) --
->>> ModelA.objects.instance_of(ModelB) -. -[ <ModelB: id 2, field1 (CharField), field2 (CharField)>, - <ModelC: id 3, field1 (CharField), field2 (CharField), field3 (CharField)> ] --
In general, including or excluding parts of the inheritance tree:
--ModelA.objects.instance_of(ModelB [, ModelC ...]) -ModelA.objects.not_instance_of(ModelB [, ModelC ...]) --
You can also use this feature in Q-objects (with the same result as above):
-->>> ModelA.objects.filter( Q(instance_of=ModelB) ) --
For example, cherrypicking objects from multiple derived classes -anywhere in the inheritance tree, using Q objects (with the -syntax: exact model name + three _ + field name):
-->>> ModelA.objects.filter( Q(ModelB___field2 = 'B2') | Q(ModelC___field3 = 'C3') ) -. -[ <ModelB: id 2, field1 (CharField), field2 (CharField)>, - <ModelC: id 3, field1 (CharField), field2 (CharField), field3 (CharField)> ] --
Querysets could 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) -. -[ <ModelX: id 1, field_x (CharField)>, - <ModelY: id 2, field_y (CharField)> ] --
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('ModelA') # ManyToMany relation to a polymorphic model
-
->>> o=RelatingModel.objects.create()
->>> o.many2many.add(ModelA.objects.get(id=1))
->>> o.many2many.add(ModelB.objects.get(id=2))
->>> o.many2many.add(ModelC.objects.get(id=3))
-
->>> o.many2many.all()
-[ <ModelA: id 1, field1 (CharField)>,
- <ModelB: id 2, field1 (CharField), field2 (CharField)>,
- <ModelC: id 3, field1 (CharField), field2 (CharField), field3 (CharField)> ]
-
-Third party models can be used as polymorphic models without -restrictions by subclassing them. E.g. using a third party -model as the root of a polymorphic inheritance tree:
--from thirdparty import ThirdPartyModel - -class MyThirdPartyBaseModel(PolymorhpicModel, ThirdPartyModel): - pass # or add fields --
Or instead integrating the third party model anywhere into an -existing polymorphic inheritance tree:
--class MyBaseModel(SomePolymorphicModel): - my_field = models.CharField(max_length=10) - -class MyModelWithThirdParty(MyBaseModel, ThirdPartyModel): - pass # or add fields --
If you insert .non_polymorphic() anywhere into the query chain, then -django_polymorphic will simply leave out the final step of retrieving the -real objects, and the manager/queryset will return objects of the type of -the base class you used for the query, like vanilla Django would -(ModelA in this example).
-->>> qs=ModelA.objects.non_polymorphic().all() ->>> qs -[ <ModelA: id 1, field1 (CharField)>, - <ModelA: id 2, field1 (CharField)>, - <ModelA: id 3, field1 (CharField)> ] --
There are no other changes in the behaviour of the queryset. For example, -enhancements for filter() or instance_of() etc. still work as expected. -If you do the final step yourself, you get the usual polymorphic result:
-->>> ModelA.objects.get_real_instances(qs) -[ <ModelA: id 1, field1 (CharField)>, - <ModelB: id 2, field1 (CharField), field2 (CharField)>, - <ModelC: id 3, field1 (CharField), field2 (CharField), field3 (CharField)> ] --
The queryset enhancements (e.g. instance_of) only work as arguments -to the member functions of a polymorphic queryset. Occationally it may -be useful to be able to use Q objects with these enhancements in other places. -As Django doesn't understand these enhanced Q objects, you need to -transform them manually into normal Q objects before you can feed them -to a Django queryset or function:
--normal_q_object = ModelA.translate_polymorphic_Q_object( Q(instance_of=Model2B) ) --
This function cannot be used at model creation time however (in models.py), -as it may need to access the ContentTypes database table.
-In order to get the output as seen in all examples here, you need to use the -ShowFieldType class mixin:
--from polymorphic import PolymorphicModel, ShowFieldType - -class ModelA(ShowFieldType, PolymorphicModel): - field1 = models.CharField(max_length=10) --
You may also use ShowFieldContent or ShowFieldTypeAndContent to display -additional information when printing querysets (or converting them to text).
-When showing field contents, they will be truncated to 20 characters. You can -modify this behaviour by setting a class variable in your model like this:
--class ModelA(ShowFieldType, PolymorphicModel): - polymorphic_showfield_max_field_width = 20 - ... --
Similarly, pre-V1.0 output formatting can be re-estated by using -polymorphic_showfield_old_format = True.
-A nice feature of Django is the possibility to define one's own custom object managers. -This is fully supported with django_polymorphic: For creating a custom polymorphic -manager class, just derive your manager from PolymorphicManager instead of -models.Manager. As with vanilla Django, in your model class, you should -explicitly add the default manager first, and then your custom manager:
-
- from polymorphic import PolymorphicModel, PolymorphicManager
-
-class TimeOrderedManager(PolymorphicManager):
- def get_query_set(self):
- qs = super(TimeOrderedManager,self).get_query_set()
- return qs.order_by('-start_date') # order the queryset
-
- def most_recent(self):
- qs = self.get_query_set() # get my ordered queryset
- return qs[:10] # limit => get ten most recent entries
-
- class Project(PolymorphicModel):
- objects = PolymorphicManager() # add the default polymorphic manager first
- objects_ordered = TimeOrderedManager() # then add your own manager
- start_date = DateTimeField() # project start is this date/time
-
-The first manager defined ('objects' in the example) is used by -Django as automatic manager for several purposes, including accessing -related objects. It must not filter objects and it's safest to use -the plain PolymorphicManager here.
-Polymorphic models inherit/propagate all managers from their -base models, as long as these are polymorphic. This means that all -managers defined in polymorphic base models continue to work as -expected in models inheriting from this base model:
-
-from polymorphic import PolymorphicModel, PolymorphicManager
-
-class TimeOrderedManager(PolymorphicManager):
- def get_query_set(self):
- qs = super(TimeOrderedManager,self).get_query_set()
- return qs.order_by('-start_date') # order the queryset
-
- def most_recent(self):
- qs = self.get_query_set() # get my ordered queryset
- return qs[:10] # limit => get ten most recent entries
-
- class Project(PolymorphicModel):
- objects = PolymorphicManager() # add the default polymorphic manager first
- objects_ordered = TimeOrderedManager() # then add your own manager
- start_date = DateTimeField() # project start is this date/time
-
- class ArtProject(Project): # inherit from Project, inheriting its fields and managers
- artist = models.CharField(max_length=30)
-
-ArtProject inherited the managers objects and objects_ordered from Project.
-ArtProject.objects_ordered.all() will return all art projects ordered -regarding their start time and ArtProject.objects_ordered.most_recent() -will return the ten most recent art projects. -.
-The PolymorphicManager class accepts one initialization argument, -which is the queryset class the manager should use. Just as with vanilla Django, -you may define your own custom queryset classes. Just use PolymorphicQuerySet -instead of Django's QuerySet as the base class:
--from polymorphic import PolymorphicModel, PolymorphicManager, PolymorphicQuerySet - -class MyQuerySet(PolymorphicQuerySet): - def my_queryset_method(...): - ... - -class MyModel(PolymorphicModel): - my_objects=PolymorphicManager(MyQuerySet) - ... --
The current implementation is rather simple and does not use any -custom SQL or Django DB layer internals - it is purely based on the -standard Django ORM.
-Specifically, the query:
--result_objects = list( ModelA.objects.filter(...) ) --
performs one SQL query to retrieve ModelA objects and one additional -query for each unique derived class occurring in result_objects. -The best case for retrieving 100 objects is 1 SQL query if all are -class ModelA. If 50 objects are ModelA and 50 are ModelB, then -two queries are executed. The pathological worst case is 101 db queries if -result_objects contains 100 different object types (with all of them -subclasses of ModelA).
-Usually, when Django users create their own polymorphic ad-hoc solution -without a tool like django_polymorphic, this usually results in a variation of
--result_objects = [ o.get_real_instance() for o in BaseModel.objects.filter(...) ] --
which has very bad performance, as it introduces one additional -SQL query for every object in the result which is not of class BaseModel.
-Compared to these solutions, django_polymorphic has the advantage -that it only needs one sql request per object type, and not per object.
-Current relational DBM systems seem to have general problems with -the SQL queries produced by object relational mappers like the Django -ORM, if these use multi-table inheritance like Django's ORM does. -The "inner joins" in these queries can perform very badly. -This is independent of django_polymorphic and affects all uses of -multi table Model inheritance.
-Concrete benchmark results are forthcoming (please see discussion forum).
-Please also see this post (and comments) from Jacob Kaplan-Moss.
-Django_polymorphic works well for a considerable number of users now, -and no major problems have shown up for many months. -The API can be considered stable beginning with the V1.0 release.
-Let's assume the models ArtProject and ResearchProject are derived -from the model Project, and let's store one of each into the database:
-->>> Project.objects.create(topic="Department Party") ->>> ArtProject.objects.create(topic="Painting with Tim", artist="T. Turner") ->>> ResearchProject.objects.create(topic="Swallow Aerodynamics", supervisor="Dr. Winter") --
If we want to retrieve all our projects, we do:
-->>> Project.objects.all() --
Using django_polymorphic, we simply get what we stored:
--[ <Project: id 1, topic "Department Party">, - <ArtProject: id 2, topic "Painting with Tim", artist "T. Turner">, - <ResearchProject: id 3, topic "Swallow Aerodynamics", supervisor "Dr. Winter"> ] --
Using vanilla Django, we get incomplete objects, which is probably not what we wanted:
--[ <Project: id 1, topic "Department Party">, - <Project: id 2, topic "Painting with Tim">, - <Project: id 3, topic "Swallow Aerodynamics"> ] --
It's very similar for ForeignKeys, ManyToManyFields or OneToOneFields.
-In general, the effect of django_polymorphic is twofold:
-On one hand it makes sure that model inheritance just works as you -expect, by simply ensuring that you always get back exactly the same -objects from the database you stored there - regardless how you access -them, making model inheritance much more "pythonic". -This can save you a lot of unpleasant workarounds that tend to -make your code messy, error-prone, and slow.
-On the other hand, together with some small API additions to the Django -ORM, django_polymorphic enables a much more expressive and intuitive -programming style and also very advanced object oriented designs -that are not possible with vanilla Django.
-Fortunately, most of the heavy duty machinery that is needed for this -functionality is already present in the original Django database layer. -Django_polymorphic adds a rather thin layer above that in order -to make real OO fully automatic and very easy to use.
-There is a catch however, which applies to concrete model inheritance -in general: Current DBM systems like PostgreSQL or MySQL are not very -good at processing the required sql queries and can be rather slow in -many cases. Concrete benchmarks are forthcoming (please see -discussion forum).
-For more information, please look at Quickstart or at the complete -Installation and Usage Docs and also see the restrictions and caveats.
-The release contains a considerable amount of changes in some of the more -critical parts of the software. It's intended for testing and development -environments and not for production environments. For these, it's best to -wait a few weeks for the proper V1.0 release, to allow some time for any -potential problems to turn up (if they exist).
-If you encounter any problems or have suggestions regarding the API or the -changes in this beta, please post them in the discussion group -or open an issue on GitHub or BitBucket (or send me an email).
-Django_polymorphic uses the same license as Django (BSD-like).
-.extra() has been re-implemented. Now it's polymorphic by -default and works (nearly) without restrictions (please see docs). This is a (very) -incompatible API change regarding previous versions of django_polymorphic. -Support for the polymorphic keyword parameter has been removed. -You can get back the non-polymorphic behaviour by using -ModelA.objects.non_polymorphic().extra().
-In order to improve compatibility with vanilla Django, printing quersets -(__repr__ and __unicode__) does not use django_polymorphic's pretty printing -by default anymore. To get the old behaviour when printing querysets, -you need to replace your model definition:
-->>> class Project(PolymorphicModel): --
by:
-->>> class Project(PolymorphicModel, ShowFieldType): --
The mixin classes for pretty output have been renamed:
--ShowFieldTypes, ShowFields, ShowFieldsAndTypes-
are now:
--ShowFieldType, ShowFieldContent and ShowFieldTypeAndContent-
(the old ones still exist for compatibility)
-ShowFieldContent and ShowFieldTypeAndContent now -use a slightly different output format. If this causes too much trouble for -your test cases, you can get the old behaviour back (mostly) by adding -polymorphic_showfield_old_format = True to your model definitions. -ShowField... now also produces more informative output for custom -primary keys.
-The polymorphic_dumpdata management command is not needed anymore -and has been disabled, as the regular Django dumpdata command now automatically -works correctly with polymorphic models (for all supported versions of Django).
-Django 1.3 requires python manage.py test polymorphic instead of -just python manage.py test.
-.non_polymorphic() queryset member function added. This is preferable to -using .base_objects..., as it just makes the resulting queryset non-polymorphic -and does not change anything else in the behaviour of the manager used (while -.base_objects is just a different manager).
-.get_real_instances() has been elevated to an official part of the API. -It allows you to turn a queryset or list of base objects into a list of the real instances. -This is useful if e.g. you use ModelA.objects.non_polymorphic().extra(...) and then want to -transform the result to its polymorphic equivalent:
-->>> qs = ModelA.objects.all().non_polymorphic() ->>> real_objects = qs.get_real_instances() --
is equivalent to:
-->>> real_objects = ModelA.objects.all() --
Instead of qs.get_real_instances(), ModelA.objects.get_real_instances(qs) may be used -as well. In the latter case, qs may be any list of objects of type ModelA.
-translate_polymorphic_Q_object (see DOCS)
-The django_polymorphic source code has been restructured -and as a result needs to be installed like a normal Django App -- either via copying the "polymorphic" directory into your -Django project or by running setup.py. Adding 'polymorphic' -to INSTALLED_APPS in settings.py is still optional, however.
-The file polymorphic.py cannot be used as a standalone -extension module anymore (as is has been split into a number -of smaller files).
-Importing works slightly different now: All relevant symbols are -imported directly from 'polymorphic' instead from -'polymorphic.models':
--# new way -from polymorphic import PolymorphicModel, ... - -# old way, doesn't work anymore -from polymorphic.models import PolymorphicModel, ... --
The update from January 26 changed the database schema (more info in the commit-log). -Sorry for any inconvenience. But this should be the final DB schema now.
-