some doc + minor code updates (__repr__ + Show... mixins)
parent
2fcb7fba1a
commit
2795f7acd5
40
DOCS.rst
40
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
|
||||
|
|
|
|||
31
README.rst
31
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::
|
|||
[ <Project: id 1, topic: "John's Gathering">,
|
||||
<ArtProject: id 2, topic: "Sculpting with Tim", artist: "T. Turner">,
|
||||
<ResearchProject: id 3, topic: "Swallow Aerodynamics", supervisor: "Dr. Winter"> ]
|
||||
|
||||
|
||||
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
|
||||
------
|
||||
|
|
|
|||
|
|
@ -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 + '>'
|
||||
|
||||
|
|
|
|||
|
|
@ -146,9 +146,9 @@ class testclass(TestCase):
|
|||
|
||||
# test ordering
|
||||
expected = '''
|
||||
[ <BlogB: id 4, name (CharField): "Bb3", >,
|
||||
<BlogB: id 3, name (CharField): "Bb2", >,
|
||||
<BlogB: id 2, name (CharField): "Bb1", >,
|
||||
[ <BlogB: id 4, name (CharField): "Bb3">,
|
||||
<BlogB: id 3, name (CharField): "Bb2">,
|
||||
<BlogB: id 2, name (CharField): "Bb1">,
|
||||
<BlogA: id 8, name (CharField): "B5", info (CharField): "i5">,
|
||||
<BlogA: id 7, name (CharField): "B4", info (CharField): "i4">,
|
||||
<BlogA: id 6, name (CharField): "B3", info (CharField): "i3">,
|
||||
|
|
@ -163,9 +163,9 @@ class testclass(TestCase):
|
|||
<BlogA: id 6, name (CharField): "B3", info (CharField): "i3">,
|
||||
<BlogA: id 5, name (CharField): "B2", info (CharField): "i2">,
|
||||
<BlogA: id 1, name (CharField): "B1", info (CharField): "i1">,
|
||||
<BlogB: id 2, name (CharField): "Bb1", >,
|
||||
<BlogB: id 3, name (CharField): "Bb2", >,
|
||||
<BlogB: id 4, name (CharField): "Bb3", > ]'''
|
||||
<BlogB: id 2, name (CharField): "Bb1">,
|
||||
<BlogB: id 3, name (CharField): "Bb2">,
|
||||
<BlogB: id 4, name (CharField): "Bb3"> ]'''
|
||||
x = '\n' + repr(BlogBase.objects.order_by('-BlogA___info'))
|
||||
assert x == expected
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue