Code

Ticket #12235: models.py

File models.py, 4.0 KB (added by bruce@…, 5 years ago)
Line 
1"""To recreate the error, just start an app and drop in this file.
2Pull up the admin interface. And add a Book.  You can go ahead and add
3one or more Authors at the same time.  Save your changes.
4
5This should work with no errors.  The error occurs when you save a Book
6object in the Admin interface that has one or more Authors assigned to it.
7
8That is, after creating a Book with one or more Authors and saving it, go back
9and edit that Book again in the admin interface.  Don't have to change
10anything, just click Save and this is the error that is generated:
11
12
13KeyError at /admin/uuid_test/book/6b31461e-ffa2-11dd-be8a-0019dbb65276/
14
15None
16
17Request Method:     POST
18Request URL:        http://localhost:8000/admin/uuid_test/book/6b31461e-ffa2-11dd-be8a-0019dbb65276/
19Exception Type:     KeyError
20Exception Value:    None
21
22Exception Location: /usr/local/lib/python2.5/site-packages/django/forms/models.py in save_existing_objects, line 411
23Python Executable:  /usr/bin/python
24Python Version:     2.5.2
25Python Path:        [...]
26Server time:        Fri, 20 Feb 2009 17:03:31 -0600
27"""
28from django.db import models
29from django.db.models import CharField
30from django.contrib import admin
31try:
32    import uuid
33except ImportError:
34    from django_extensions.utils import uuid
35
36# UUIDVersionError and UUIDField are taken directly from the django-extensions
37# project with no alterations.  I bundled them in this little test case
38# so you wouldn't have to install django-extensions just to run the test.
39class UUIDVersionError(Exception):
40    pass
41
42class UUIDField(CharField):
43    """ UUIDField
44
45    By default uses UUID version 1 (generate from host ID, sequence number and current time)
46
47    The field support all uuid versions which are natively supported by the uuid python module.
48    For more information see: http://docs.python.org/lib/module-uuid.html
49    """
50
51    def __init__(self, verbose_name=None, name=None, auto=True, version=1, node=None, clock_seq=None, namespace=None, **kwargs):
52        kwargs['max_length'] = 36
53        if auto:
54            kwargs['blank'] = True
55            kwargs.setdefault('editable', False)
56        self.auto = auto
57        self.version = version
58        if version==1:
59            self.node, self.clock_seq = node, clock_seq
60        elif version==3 or version==5:
61            self.namespace, self.name = namespace, name
62        CharField.__init__(self, verbose_name, name, **kwargs)
63
64    def get_internal_type(self):
65        return CharField.__name__
66
67    def create_uuid(self):
68        if not self.version or self.version==4:
69            return uuid.uuid4()
70        elif self.version==1:
71            return uuid.uuid1(self.node, self.clock_seq)
72        elif self.version==2:
73            raise UUIDVersionError("UUID version 2 is not supported.")
74        elif self.version==3:
75            return uuid.uuid3(self.namespace, self.name)
76        elif self.version==5:
77            return uuid.uuid5(self.namespace, self.name)
78        else:
79            raise UUIDVersionError("UUID version %s is not valid." % self.version)
80
81    def pre_save(self, model_instance, add):
82        if self.auto and add:
83            value = unicode(self.create_uuid())
84            setattr(model_instance, self.attname, value)
85            return value
86        else:
87            value = super(UUIDField, self).pre_save(model_instance, add)
88            if self.auto and not value:
89                value = unicode(self.create_uuid())
90                setattr(model_instance, self.attname, value)
91        return value
92
93
94class Book(models.Model):
95    id = UUIDField(primary_key=True, auto_created=False)
96    title = models.CharField(max_length=128)
97    def __unicode__(self):
98        return unicode(self.title)
99
100class Author(models.Model):
101    id = UUIDField(primary_key=True, auto_created=False)
102    book = models.ForeignKey(Book)
103    name = models.CharField(max_length=128)
104    def __unicode(self):
105        return unicode(self.name)
106
107
108class AuthorInlineAdmin(admin.TabularInline):
109    model=Author
110
111class BookAdmin(admin.ModelAdmin):
112    inlines = (AuthorInlineAdmin, )
113admin.site.register(Book, BookAdmin)