some doc + minor code updates (__repr__ + Show... mixins)

fix_request_path_info
Bert Constantin 2010-02-04 18:09:15 +01:00
parent 2fcb7fba1a
commit 2795f7acd5
4 changed files with 53 additions and 45 deletions

View File

@ -7,18 +7,18 @@ Installation / Testing
Requirements Requirements
------------ ------------
Django 1.1 (or later) and Python 2.5 (or later). This code has been tested Django 1.1 (or later) and Python 2.5/2.6. This code has been tested
on Django 1.1.1 / 1.2 alpha and Python 2.5.4 / 2.6.4 on Linux. on Django 1.1.1 / 1.2 beta and Python 2.5.4 / 2.6.4 on Linux.
Testing Testing
------- -------
The repository (or tar file) contains a complete Django project The repository (or tar file) contains a complete Django project
that may be used for tests or experiments. that may be used for tests or experiments (without any installation needed).
To run the included test suite, execute:: To run the included test suite, execute::
./manage test polymorphic ./manage test
The management command ``pcmd.py`` in the app ``pexp`` (Polymorphic EXPerimenting) The management command ``pcmd.py`` in the app ``pexp`` (Polymorphic EXPerimenting)
can be used for experiments - modify this file (pexp/management/commands/pcmd.py) 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). option (fixed in Django 1.2).
* Django 1.1 only - when ContentType is used in models, Django's * Django 1.1 only - when ContentType is used in models, Django's
seralisation or fixtures cannot be used. This issue seems to be seralisation or fixtures cannot be used (all polymorphic models
resolved for Django 1.2 (changeset 11863: Fixed #7052, Added support use ContentType). This issue seems to be resolved for Django 1.2
for natural keys in serialization). (changeset 11863: Fixed #7052, Added support for natural keys in serialization).
+ http://code.djangoproject.com/ticket/7052 + http://code.djangoproject.com/ticket/7052
+ http://stackoverflow.com/questions/853796/problems-with-contenttypes-when-loading-a-fixture-in-django + 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 This problem is aggravated when trying to enhance models.Model
by subclassing it instead of modifying Django core (as we do here by subclassing it instead of modifying Django core (as we do here
with PolymorphicModel). 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 * A reference (``ContentType``) to the real/leaf model is stored
in the base model (the base model directly inheriting from in the base model (the base model directly inheriting from
PolymorphicModel). If a model or an app is renamed, then Django's 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 in PolymorphicModel, which causes some overhead. A minor patch to
Django core would probably get rid of that. Django core would probably get rid of that.
Project Status Project Status
-------------- ==============
It's important to consider that this code is very new and It's important to consider that this code is very new and
to some extent still experimental. Please see the docs for to some extent still experimental. It does seem to work very
current restrictions, caveats, and performance implications. well for a number of people, but API changes, code reorganisations
or further schema changes are still a possibility. There may also
It does seem to work very well for a number of people, but remain larger bugs and problems in the code that have not yet
API changes, code reorganisations or further schema changes been found.
are still a possibility. There may also remain larger bugs
and problems in the code that have not yet been found.
Links Links

View File

@ -2,11 +2,15 @@ Release Notes, Usage, Code
-------------------------- --------------------------
* Please see `here for release notes, news and discussion`_ (Google Group) * Please see `here for release notes, news and discussion`_ (Google Group)
* Installation and usage: `Documentation and Examples`_ (or the short `Overview`_) * `Many Examples`_, or full `Installation and Usage Docs`_ (or the short `Overview`_)
* The code is on GitHub_ and Bitbucket_ and can also be downloaded as TGZ_ or ZIP_ * 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 .. _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 .. _GitHub: http://github.com/bconstantin/django_polymorphic
.. _Bitbucket: http://bitbucket.org/bconstantin/django_polymorphic .. _Bitbucket: http://bitbucket.org/bconstantin/django_polymorphic
.. _TGZ: http://github.com/bconstantin/django_polymorphic/tarball/master .. _TGZ: http://github.com/bconstantin/django_polymorphic/tarball/master
@ -17,14 +21,8 @@ Release Notes, Usage, Code
What is django_polymorphic good for? What is django_polymorphic good for?
------------------------------------ ------------------------------------
It implements seamless polymorphic inheritance for Django models. **Example**: If we define the model ``Project`` as the base class for
our models ``ArtProject`` and ``ResearchProject``, and we store one of
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
each into the database, then we can do:: each into the database, then we can do::
>>> Project.objects.all() >>> Project.objects.all()
@ -32,7 +30,12 @@ each into the database, then we can do::
[ <Project: id 1, topic: "John's Gathering">, [ <Project: id 1, topic: "John's Gathering">,
<ArtProject: id 2, topic: "Sculpting with Tim", artist: "T. Turner">, <ArtProject: id 2, topic: "Sculpting with Tim", artist: "T. Turner">,
<ResearchProject: id 3, topic: "Swallow Aerodynamics", supervisor: "Dr. Winter"> ] <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 It doesn't matter how these objects are retrieved: be it through the
model's own managers/querysets, ForeignKeys, ManyToManyFields model's own managers/querysets, ForeignKeys, ManyToManyFields
or OneToOneFields. or OneToOneFields.
@ -45,8 +48,10 @@ django_polymorphic does this only for models that explicitely enable it
(and for their submodels). (and for their submodels).
Please see the `Documentation and Examples`_ for more information 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 Status
------ ------

View File

@ -710,42 +710,39 @@ class PolymorphicModel(models.Model):
super(PolymorphicModel, self).__init__(*args, **kwargs) super(PolymorphicModel, self).__init__(*args, **kwargs)
def __repr__(self): 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: for f in self._meta.fields:
if f.name in [ 'id' ] + self.polymorphic_internal_model_fields or 'ptr' in f.name: continue 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 f != last: out += ', '
return '<' + out + '>' return '<' + out + '>'
class ShowFields(object): class ShowFields(object):
""" model mixin that shows the object's class, it's fields and field contents """ """ model mixin that shows the object's class, it's fields and field contents """
def __repr__(self): def __repr__(self):
out = 'id %d, ' % (self.pk); last = self._meta.fields[-1] out = 'id %d, ' % (self.pk)
for f in self._meta.fields: for f in self._meta.fields:
if f.name in [ 'id' ] + self.polymorphic_internal_model_fields or 'ptr' in f.name: continue 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)): if isinstance(f, (models.ForeignKey)):
o = getattr(self, f.name) o = getattr(self, f.name)
out += ': "' + ('None' if o == None else o.__class__.__name__) + '"' out += ': "' + ('None' if o == None else o.__class__.__name__) + '"'
else: else:
out += ': "' + getattr(self, f.name) + '"' out += ': "' + getattr(self, f.name) + '"'
if f != last: out += ', '
return '<' + (self.__class__.__name__ + ': ') + out + '>' return '<' + (self.__class__.__name__ + ': ') + out + '>'
class ShowFieldsAndTypes(object): class ShowFieldsAndTypes(object):
""" model mixin, like ShowFields, but also show field types """ """ model mixin, like ShowFields, but also show field types """
def __repr__(self): def __repr__(self):
out = 'id %d, ' % (self.pk); last = self._meta.fields[-1] out = 'id %d' % (self.pk)
for f in self._meta.fields: for f in self._meta.fields:
if f.name in [ 'id' ] + self.polymorphic_internal_model_fields or 'ptr' in f.name: continue 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)): if isinstance(f, (models.ForeignKey)):
o = getattr(self, f.name) o = getattr(self, f.name)
out += ': "' + ('None' if o == None else o.__class__.__name__) + '"' out += ': "' + ('None' if o == None else o.__class__.__name__) + '"'
else: else:
out += ': "' + getattr(self, f.name) + '"' out += ': "' + getattr(self, f.name) + '"'
if f != last: out += ', '
return '<' + self.__class__.__name__ + ': ' + out + '>' return '<' + self.__class__.__name__ + ': ' + out + '>'

View File

@ -146,9 +146,9 @@ class testclass(TestCase):
# test ordering # test ordering
expected = ''' expected = '''
[ <BlogB: id 4, name (CharField): "Bb3", >, [ <BlogB: id 4, name (CharField): "Bb3">,
<BlogB: id 3, name (CharField): "Bb2", >, <BlogB: id 3, name (CharField): "Bb2">,
<BlogB: id 2, name (CharField): "Bb1", >, <BlogB: id 2, name (CharField): "Bb1">,
<BlogA: id 8, name (CharField): "B5", info (CharField): "i5">, <BlogA: id 8, name (CharField): "B5", info (CharField): "i5">,
<BlogA: id 7, name (CharField): "B4", info (CharField): "i4">, <BlogA: id 7, name (CharField): "B4", info (CharField): "i4">,
<BlogA: id 6, name (CharField): "B3", info (CharField): "i3">, <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 6, name (CharField): "B3", info (CharField): "i3">,
<BlogA: id 5, name (CharField): "B2", info (CharField): "i2">, <BlogA: id 5, name (CharField): "B2", info (CharField): "i2">,
<BlogA: id 1, name (CharField): "B1", info (CharField): "i1">, <BlogA: id 1, name (CharField): "B1", info (CharField): "i1">,
<BlogB: id 2, name (CharField): "Bb1", >, <BlogB: id 2, name (CharField): "Bb1">,
<BlogB: id 3, name (CharField): "Bb2", >, <BlogB: id 3, name (CharField): "Bb2">,
<BlogB: id 4, name (CharField): "Bb3", > ]''' <BlogB: id 4, name (CharField): "Bb3"> ]'''
x = '\n' + repr(BlogBase.objects.order_by('-BlogA___info')) x = '\n' + repr(BlogBase.objects.order_by('-BlogA___info'))
assert x == expected assert x == expected