From 2795f7acd5889d33e586929ad87b1cc6d1c97762 Mon Sep 17 00:00:00 2001 From: Bert Constantin Date: Thu, 4 Feb 2010 18:09:15 +0100 Subject: [PATCH] some doc + minor code updates (__repr__ + Show... mixins) --- DOCS.rst | 40 ++++++++++++++++++++++---------------- README.rst | 31 ++++++++++++++++------------- polymorphic/polymorphic.py | 15 ++++++-------- polymorphic/tests.py | 12 ++++++------ 4 files changed, 53 insertions(+), 45 deletions(-) diff --git a/DOCS.rst b/DOCS.rst index c0e6859..8a0a1b3 100644 --- a/DOCS.rst +++ b/DOCS.rst @@ -7,18 +7,18 @@ Installation / Testing Requirements ------------ -Django 1.1 (or later) and Python 2.5 (or later). This code has been tested -on Django 1.1.1 / 1.2 alpha and Python 2.5.4 / 2.6.4 on Linux. +Django 1.1 (or later) and Python 2.5/2.6. This code has been tested +on Django 1.1.1 / 1.2 beta and Python 2.5.4 / 2.6.4 on Linux. Testing ------- -The repository (or tar file) contains a complete Django project -that may be used for tests or experiments. +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, execute:: - ./manage test polymorphic + ./manage test The management command ``pcmd.py`` in the app ``pexp`` (Polymorphic EXPerimenting) can be used for experiments - modify this file (pexp/management/commands/pcmd.py) @@ -394,9 +394,9 @@ Restrictions & Caveats option (fixed in Django 1.2). * Django 1.1 only - when ContentType is used in models, Django's - seralisation or fixtures cannot be used. This issue seems to be - resolved for Django 1.2 (changeset 11863: Fixed #7052, Added support - for natural keys in serialization). + seralisation or fixtures cannot be used (all polymorphic models + use ContentType). This issue seems to be resolved for Django 1.2 + (changeset 11863: Fixed #7052, Added support for natural keys in serialization). + http://code.djangoproject.com/ticket/7052 + http://stackoverflow.com/questions/853796/problems-with-contenttypes-when-loading-a-fixture-in-django @@ -408,7 +408,14 @@ Restrictions & Caveats This problem is aggravated when trying to enhance models.Model by subclassing it instead of modifying Django core (as we do here with PolymorphicModel). - + +* It must be possible to instantiate the base model objects, even if your + application never does this itself. This is needed by the current + implementation of polymorphic querysets but (likely) also by Django internals. + Example: If ModelB and ModelC inherit from ModelA, and you never create + ModelA objects, django_polymorphic and Django core will still instantiate + ModelA objects for temporary purposes (and fail, if this isn't possible). + * A reference (``ContentType``) to the real/leaf model is stored in the base model (the base model directly inheriting from PolymorphicModel). If a model or an app is renamed, then Django's @@ -428,17 +435,16 @@ Restrictions & Caveats in PolymorphicModel, which causes some overhead. A minor patch to Django core would probably get rid of that. + Project Status --------------- +============== It's important to consider that this code is very new and -to some extent still experimental. Please see the docs for -current restrictions, caveats, and performance implications. - -It does seem to work very well for a number of people, but -API changes, code reorganisations or further schema changes -are still a possibility. There may also remain larger bugs -and problems in the code that have not yet been found. +to some extent still experimental. It does seem to work very +well for a number of people, but API changes, code reorganisations +or further schema changes are still a possibility. There may also +remain larger bugs and problems in the code that have not yet +been found. Links diff --git a/README.rst b/README.rst index 9268586..7391be8 100644 --- a/README.rst +++ b/README.rst @@ -2,11 +2,15 @@ Release Notes, Usage, Code -------------------------- * Please see `here for release notes, news and discussion`_ (Google Group) -* Installation and usage: `Documentation and Examples`_ (or the short `Overview`_) -* The code is on GitHub_ and Bitbucket_ and can also be downloaded as TGZ_ or ZIP_ +* `Many Examples`_, or full `Installation and Usage Docs`_ (or the short `Overview`_) +* Download from GitHub_ or Bitbucket_, or as TGZ_ or ZIP_ +* Improve django_polymorphic: Report issues, discuss, post patch, or fork the code (GitHub_, Bitbucket_, Newsgroup_, Mail_) .. _here for release notes, news and discussion: http://groups.google.de/group/django-polymorphic/topics -.. _Documentation and Examples: http://bserve.webhop.org/wiki/django_polymorphic/doc +.. _Newsgroup: http://groups.google.de/group/django-polymorphic/topics +.. _Mail: http://github.com/bconstantin/django_polymorphic/tree/master/setup.py +.. _Installation and Usage Docs: http://bserve.webhop.org/wiki/django_polymorphic/doc +.. _Many Examples: http://bserve.webhop.org/wiki/django_polymorphic/doc#defining-polymorphic-models .. _GitHub: http://github.com/bconstantin/django_polymorphic .. _Bitbucket: http://bitbucket.org/bconstantin/django_polymorphic .. _TGZ: http://github.com/bconstantin/django_polymorphic/tarball/master @@ -17,14 +21,8 @@ Release Notes, Usage, Code What is django_polymorphic good for? ------------------------------------ -It implements seamless polymorphic inheritance for Django models. - -This means: objects being retrieved from the database are always returned -back with the same type/class and fields they were created and saved with. - -An example: -If we defined the model ``Project`` as a base class for our models -``ArtProject`` and ``ResearchProject``, and we have stored one of +**Example**: If we define the model ``Project`` as the base class for +our models ``ArtProject`` and ``ResearchProject``, and we store one of each into the database, then we can do:: >>> Project.objects.all() @@ -32,7 +30,12 @@ each into the database, then we can do:: [ , , ] - + +In general: django_polymorphic implements seamless polymorphic inheritance for Django models. + +The effect: objects are always returned back from the database just +as you created them, with the same type/class and fields. + It doesn't matter how these objects are retrieved: be it through the model's own managers/querysets, ForeignKeys, ManyToManyFields or OneToOneFields. @@ -45,8 +48,10 @@ django_polymorphic does this only for models that explicitely enable it (and for their submodels). Please see the `Documentation and Examples`_ for more information -(also included as the file ``DOCS.rst`` with the source). +or directly look at `more Examples`_. +.. _Documentation and Examples: http://bserve.webhop.org/wiki/django_polymorphic/doc +.. _more Examples: http://bserve.webhop.org/wiki/django_polymorphic/doc#defining-polymorphic-models Status ------ diff --git a/polymorphic/polymorphic.py b/polymorphic/polymorphic.py index e4c2007..7306f67 100644 --- a/polymorphic/polymorphic.py +++ b/polymorphic/polymorphic.py @@ -710,42 +710,39 @@ class PolymorphicModel(models.Model): super(PolymorphicModel, self).__init__(*args, **kwargs) def __repr__(self): - out = self.__class__.__name__ + ': id %d, ' % (self.pk or - 1); last = self._meta.fields[-1] + out = self.__class__.__name__ + ': id %d' % (self.pk or - 1) for f in self._meta.fields: if f.name in [ 'id' ] + self.polymorphic_internal_model_fields or 'ptr' in f.name: continue - out += f.name + ' (' + type(f).__name__ + ')' - if f != last: out += ', ' + out += ', ' + f.name + ' (' + type(f).__name__ + ')' return '<' + out + '>' class ShowFields(object): """ model mixin that shows the object's class, it's fields and field contents """ def __repr__(self): - out = 'id %d, ' % (self.pk); last = self._meta.fields[-1] + out = 'id %d, ' % (self.pk) for f in self._meta.fields: if f.name in [ 'id' ] + self.polymorphic_internal_model_fields or 'ptr' in f.name: continue - out += f.name + out += ', ' + f.name if isinstance(f, (models.ForeignKey)): o = getattr(self, f.name) out += ': "' + ('None' if o == None else o.__class__.__name__) + '"' else: out += ': "' + getattr(self, f.name) + '"' - if f != last: out += ', ' return '<' + (self.__class__.__name__ + ': ') + out + '>' class ShowFieldsAndTypes(object): """ model mixin, like ShowFields, but also show field types """ def __repr__(self): - out = 'id %d, ' % (self.pk); last = self._meta.fields[-1] + out = 'id %d' % (self.pk) for f in self._meta.fields: if f.name in [ 'id' ] + self.polymorphic_internal_model_fields or 'ptr' in f.name: continue - out += f.name + ' (' + type(f).__name__ + ')' + out += ', ' + f.name + ' (' + type(f).__name__ + ')' if isinstance(f, (models.ForeignKey)): o = getattr(self, f.name) out += ': "' + ('None' if o == None else o.__class__.__name__) + '"' else: out += ': "' + getattr(self, f.name) + '"' - if f != last: out += ', ' return '<' + self.__class__.__name__ + ': ' + out + '>' diff --git a/polymorphic/tests.py b/polymorphic/tests.py index 1d463ce..4b9f7c0 100644 --- a/polymorphic/tests.py +++ b/polymorphic/tests.py @@ -146,9 +146,9 @@ class testclass(TestCase): # test ordering expected = ''' -[ , - , - , +[ , + , + , , , , @@ -163,9 +163,9 @@ class testclass(TestCase): , , , - , - , - ]''' + , + , + ]''' x = '\n' + repr(BlogBase.objects.order_by('-BlogA___info')) assert x == expected