~ubuntu-branches/debian/squeeze/python-django/squeeze

« back to all changes in this revision

Viewing changes to tests/modeltests/field_subclassing/models.py

  • Committer: Bazaar Package Importer
  • Author(s): Chris Lamb, Chris Lamb, David Spreen, Sandro Tosi
  • Date: 2008-11-19 21:31:00 UTC
  • mfrom: (1.2.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20081119213100-gp0lqhxl1qxa6dgl
Tags: 1.0.2-1
[ Chris Lamb ]
* New upstream bugfix release. Closes: #505783
* Add myself to Uploaders with ACK from Brett.

[ David Spreen ]
* Remove python-pysqlite2 from Recommends because Python 2.5 includes
  sqlite library used by Django. Closes: 497886

[ Sandro Tosi ]
* debian/control
  - switch Vcs-Browser field to viewsvn

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
"""
2
 
Tests for field subclassing.
3
 
"""
4
 
 
5
 
from django.db import models
6
 
from django.utils.encoding import force_unicode
7
 
from django.core import serializers
8
 
from django.core.exceptions import FieldError
9
 
 
10
 
class Small(object):
11
 
    """
12
 
    A simple class to show that non-trivial Python objects can be used as
13
 
    attributes.
14
 
    """
15
 
    def __init__(self, first, second):
16
 
        self.first, self.second = first, second
17
 
 
18
 
    def __unicode__(self):
19
 
        return u'%s%s' % (force_unicode(self.first), force_unicode(self.second))
20
 
 
21
 
    def __str__(self):
22
 
        return unicode(self).encode('utf-8')
23
 
 
24
 
class SmallField(models.Field):
25
 
    """
26
 
    Turns the "Small" class into a Django field. Because of the similarities
27
 
    with normal character fields and the fact that Small.__unicode__ does
28
 
    something sensible, we don't need to implement a lot here.
29
 
    """
30
 
    __metaclass__ = models.SubfieldBase
31
 
 
32
 
    def __init__(self, *args, **kwargs):
33
 
        kwargs['max_length'] = 2
34
 
        super(SmallField, self).__init__(*args, **kwargs)
35
 
 
36
 
    def get_internal_type(self):
37
 
        return 'CharField'
38
 
 
39
 
    def to_python(self, value):
40
 
        if isinstance(value, Small):
41
 
            return value
42
 
        return Small(value[0], value[1])
43
 
 
44
 
    def get_db_prep_save(self, value):
45
 
        return unicode(value)
46
 
 
47
 
    def get_db_prep_lookup(self, lookup_type, value):
48
 
        if lookup_type == 'exact':
49
 
            return force_unicode(value)
50
 
        if lookup_type == 'in':
51
 
            return [force_unicode(v) for v in value]
52
 
        if lookup_type == 'isnull':
53
 
            return []
54
 
        raise FieldError('Invalid lookup type: %r' % lookup_type)
55
 
 
56
 
class MyModel(models.Model):
57
 
    name = models.CharField(max_length=10)
58
 
    data = SmallField('small field')
59
 
 
60
 
    def __unicode__(self):
61
 
        return force_unicode(self.name)
62
 
 
63
 
__test__ = {'API_TESTS': ur"""
64
 
# Creating a model with custom fields is done as per normal.
65
 
>>> s = Small(1, 2)
66
 
>>> print s
67
 
12
68
 
>>> m = MyModel(name='m', data=s)
69
 
>>> m.save()
70
 
 
71
 
# Custom fields still have normal field's attributes.
72
 
>>> m._meta.get_field('data').verbose_name
73
 
'small field'
74
 
 
75
 
# The m.data attribute has been initialised correctly. It's a Small object.
76
 
>>> m.data.first, m.data.second
77
 
(1, 2)
78
 
 
79
 
# The data loads back from the database correctly and 'data' has the right type.
80
 
>>> m1 = MyModel.objects.get(pk=m.pk)
81
 
>>> isinstance(m1.data, Small)
82
 
True
83
 
>>> print m1.data
84
 
12
85
 
 
86
 
# We can do normal filtering on the custom field (and will get an error when we
87
 
# use a lookup type that does not make sense).
88
 
>>> s1 = Small(1, 3)
89
 
>>> s2 = Small('a', 'b')
90
 
>>> MyModel.objects.filter(data__in=[s, s1, s2])
91
 
[<MyModel: m>]
92
 
>>> MyModel.objects.filter(data__lt=s)
93
 
Traceback (most recent call last):
94
 
...
95
 
FieldError: Invalid lookup type: 'lt'
96
 
 
97
 
# Serialization works, too.
98
 
>>> stream = serializers.serialize("json", MyModel.objects.all())
99
 
>>> stream
100
 
'[{"pk": 1, "model": "field_subclassing.mymodel", "fields": {"data": "12", "name": "m"}}]'
101
 
>>> obj = list(serializers.deserialize("json", stream))[0]
102
 
>>> obj.object == m
103
 
True
104
 
 
105
 
# Test retrieving custom field data
106
 
>>> m.delete()
107
 
>>> m1 = MyModel(name="1", data=Small(1, 2))
108
 
>>> m1.save()
109
 
>>> m2 = MyModel(name="2", data=Small(2, 3))
110
 
>>> m2.save()
111
 
>>> for m in MyModel.objects.all(): print unicode(m.data)
112
 
12
113
 
23
114
 
"""}