initial import (with InheritanceCastModel)

--HG--
extra : convert_revision : carl%40dirtcircle.com-20090702180302-idhig8pzmbv8nv7l
This commit is contained in:
Carl Meyer 2009-07-02 14:03:02 -04:00
commit 3247ac5d4b
15 changed files with 166 additions and 0 deletions

1
AUTHORS.txt Normal file
View file

@ -0,0 +1 @@
Carl Meyer <carl@dirtcircle.com>

4
CHANGELOG.txt Normal file
View file

@ -0,0 +1,4 @@
============================
django-model-utils changelog
============================

12
INSTALL.txt Normal file
View file

@ -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/.

28
LICENSE.txt Normal file
View file

@ -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.

7
MANIFEST.in Normal file
View file

@ -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

6
README.txt Normal file
View file

@ -0,0 +1,6 @@
==================
django-model-utils
==================
Django model mixins and utilities.

3
TODO.txt Normal file
View file

@ -0,0 +1,3 @@
TODO list for django-model-utils
================================

0
model_utils/__init__.py Normal file
View file

26
model_utils/models.py Normal file
View file

@ -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

View file

View file

@ -0,0 +1,10 @@
from django.db import models
from model_utils.models import InheritanceCastModel
class InheritParent(InheritanceCastModel):
pass
class InheritChild(InheritParent):
pass

13
model_utils/tests/runtests.py Executable file
View file

@ -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')

View file

@ -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'

View file

@ -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)

24
setup.py Normal file
View file

@ -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'],
)