commit 3247ac5d4b82e42be0f2481747ec11366cd949b6 Author: Carl Meyer Date: Thu Jul 2 14:03:02 2009 -0400 initial import (with InheritanceCastModel) --HG-- extra : convert_revision : carl%40dirtcircle.com-20090702180302-idhig8pzmbv8nv7l diff --git a/AUTHORS.txt b/AUTHORS.txt new file mode 100644 index 0000000..6219fa3 --- /dev/null +++ b/AUTHORS.txt @@ -0,0 +1 @@ +Carl Meyer diff --git a/CHANGELOG.txt b/CHANGELOG.txt new file mode 100644 index 0000000..e2c34ad --- /dev/null +++ b/CHANGELOG.txt @@ -0,0 +1,4 @@ +============================ +django-model-utils changelog +============================ + diff --git a/INSTALL.txt b/INSTALL.txt new file mode 100644 index 0000000..a146b58 --- /dev/null +++ b/INSTALL.txt @@ -0,0 +1,12 @@ +To install django-model-utils, run the following command inside this +directory: + + python setup.py install + +You can also just copy the included ``model_utils`` directory somewhere +on your Python path, or symlink to it from somewhere on your Python path, or +use ``easy_install`` or ``pip``. + +This application requires Python 2.3 or later, and Django 1.0 or later. +You can obtain Python from http://www.python.org/ and Django from +http://www.djangoproject.com/. diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 0000000..f9135c0 --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,28 @@ +Copyright (c) 2009, Carl Meyer +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of the author nor the names of other + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/MANIFEST.in b/MANIFEST.in new file mode 100644 index 0000000..35fe970 --- /dev/null +++ b/MANIFEST.in @@ -0,0 +1,7 @@ +include AUTHORS.txt +include CHANGELOG.txt +include INSTALL.txt +include LICENSE.txt +include MANIFEST.in +include README.txt +include TODO.txt \ No newline at end of file diff --git a/README.txt b/README.txt new file mode 100644 index 0000000..76264cd --- /dev/null +++ b/README.txt @@ -0,0 +1,6 @@ +================== +django-model-utils +================== + +Django model mixins and utilities. + diff --git a/TODO.txt b/TODO.txt new file mode 100644 index 0000000..9378f11 --- /dev/null +++ b/TODO.txt @@ -0,0 +1,3 @@ +TODO list for django-model-utils +================================ + diff --git a/model_utils/__init__.py b/model_utils/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/model_utils/models.py b/model_utils/models.py new file mode 100644 index 0000000..c566d38 --- /dev/null +++ b/model_utils/models.py @@ -0,0 +1,26 @@ +from django.db import models +from django.contrib.contenttypes.models import ContentType + +class InheritanceCastModel(models.Model): + """ + An abstract base class that provides a ``real_type`` FK to ContentType. + + For use in trees of inherited models, to be able to downcast + parent instances to their child types. + + """ + real_type = models.ForeignKey(ContentType, editable=False, null=True) + + def save(self, *args, **kwargs): + if not self.id: + self.real_type = self._get_real_type() + super(InheritanceCastModel, self).save(*args, **kwargs) + + def _get_real_type(self): + return ContentType.objects.get_for_model(type(self)) + + def cast(self): + return self.real_type.get_object_for_this_type(pk=self.pk) + + class Meta: + abstract = True diff --git a/model_utils/tests/__init__.py b/model_utils/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/model_utils/tests/models.py b/model_utils/tests/models.py new file mode 100644 index 0000000..c10c3f3 --- /dev/null +++ b/model_utils/tests/models.py @@ -0,0 +1,10 @@ +from django.db import models + +from model_utils.models import InheritanceCastModel + +class InheritParent(InheritanceCastModel): + pass + +class InheritChild(InheritParent): + pass + diff --git a/model_utils/tests/runtests.py b/model_utils/tests/runtests.py new file mode 100755 index 0000000..3d0b5dd --- /dev/null +++ b/model_utils/tests/runtests.py @@ -0,0 +1,13 @@ +#!/usr/bin/env python + +import os, sys + +parent = os.path.dirname(os.path.dirname(os.path.dirname( + os.path.abspath(__file__)))) + +sys.path.insert(0, parent) + +from django.core.management import setup_environ, call_command +from model_utils.tests import test_settings +setup_environ(test_settings, 'model_utils.tests.test_settings') +call_command('test', 'tests') diff --git a/model_utils/tests/test_settings.py b/model_utils/tests/test_settings.py new file mode 100644 index 0000000..110e402 --- /dev/null +++ b/model_utils/tests/test_settings.py @@ -0,0 +1,11 @@ +import os + +BASE_DIR = os.path.dirname(__file__) + +INSTALLED_APPS = ( + 'django.contrib.contenttypes', + 'model_utils', + 'model_utils.tests', + ) + +DATABASE_ENGINE = 'sqlite3' diff --git a/model_utils/tests/tests.py b/model_utils/tests/tests.py new file mode 100644 index 0000000..5da2d5c --- /dev/null +++ b/model_utils/tests/tests.py @@ -0,0 +1,21 @@ +from django.test import TestCase +from django.contrib.contenttypes.models import ContentType + +from model_utils.tests.models import InheritParent, InheritChild + +class InheritanceCastModelTests(TestCase): + def setUp(self): + self.parent = InheritParent.objects.create() + self.child = InheritChild.objects.create() + + def testParentRealType(self): + self.assertEquals(self.parent.real_type, + ContentType.objects.get_for_model(InheritParent)) + + def testChildRealType(self): + self.assertEquals(self.child.real_type, + ContentType.objects.get_for_model(InheritChild)) + + def testCast(self): + obj = InheritParent.objects.get(pk=self.child.pk).cast() + self.assertEquals(obj.__class__, InheritChild) diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..bfa64dd --- /dev/null +++ b/setup.py @@ -0,0 +1,24 @@ +from setuptools import setup, find_packages + +setup( + name='django-model-utils', + version='0.1.0', + description='Django model mixins and utilities', + long_description=open('README.txt').read(), + author='Carl Meyer', + author_email='carl@dirtcircle.com', + url='http://launchpad.net/django-model-utils', + packages=find_packages(), + classifiers=[ + 'Development Status :: 3 - Alpha', + 'Environment :: Web Environment', + 'Intended Audience :: Developers', + 'License :: OSI Approved :: BSD License', + 'Operating System :: OS Independent', + 'Programming Language :: Python', + 'Framework :: Django', + ], + include_package_data=True, + zip_safe=False, + setup_requires=['setuptools_bzr'], +)