summaryrefslogtreecommitdiff
path: root/tests/modeltests
diff options
context:
space:
mode:
authorMalcolm Tredinnick <malcolm.tredinnick@gmail.com>2008-09-03 00:09:33 +0000
committerMalcolm Tredinnick <malcolm.tredinnick@gmail.com>2008-09-03 00:09:33 +0000
commit85ebb91846fd5bb1a766d1bed905d6f60667274c (patch)
tree729a224e9af03781040dccca0d1d355a018f2e8f /tests/modeltests
parent0e5faf225c5cd1acf2ab653c74f5b161470403b9 (diff)
downloaddjango-85ebb91846fd5bb1a766d1bed905d6f60667274c.tar.gz
Fixed #8669 -- Use a consistent version of create() across the board for
model/field instance creation. Based on a patch from Richard Davies. git-svn-id: http://code.djangoproject.com/svn/django/trunk@8884 bcc190cf-cafb-0310-a4f2-bffc1f526a37
Diffstat (limited to 'tests/modeltests')
-rw-r--r--tests/modeltests/custom_pk/models.py77
-rw-r--r--tests/modeltests/get_or_create/models.py19
2 files changed, 76 insertions, 20 deletions
diff --git a/tests/modeltests/custom_pk/models.py b/tests/modeltests/custom_pk/models.py
index e3edf3187e..091f7f32b4 100644
--- a/tests/modeltests/custom_pk/models.py
+++ b/tests/modeltests/custom_pk/models.py
@@ -6,11 +6,11 @@ By default, Django adds an ``"id"`` field to each model. But you can override
this behavior by explicitly adding ``primary_key=True`` to a field.
"""
-from django.db import models
+from django.conf import settings
+from django.db import models, transaction, IntegrityError
class Employee(models.Model):
- employee_code = models.CharField(max_length=10, primary_key=True,
- db_column = 'code')
+ employee_code = models.IntegerField(primary_key=True, db_column = 'code')
first_name = models.CharField(max_length=20)
last_name = models.CharField(max_length=20)
class Meta:
@@ -29,50 +29,50 @@ class Business(models.Model):
return self.name
__test__ = {'API_TESTS':"""
->>> dan = Employee(employee_code='ABC123', first_name='Dan', last_name='Jones')
+>>> dan = Employee(employee_code=123, first_name='Dan', last_name='Jones')
>>> dan.save()
>>> Employee.objects.all()
[<Employee: Dan Jones>]
->>> fran = Employee(employee_code='XYZ456', first_name='Fran', last_name='Bones')
+>>> fran = Employee(employee_code=456, first_name='Fran', last_name='Bones')
>>> fran.save()
>>> Employee.objects.all()
[<Employee: Fran Bones>, <Employee: Dan Jones>]
->>> Employee.objects.get(pk='ABC123')
+>>> Employee.objects.get(pk=123)
<Employee: Dan Jones>
->>> Employee.objects.get(pk='XYZ456')
+>>> Employee.objects.get(pk=456)
<Employee: Fran Bones>
->>> Employee.objects.get(pk='foo')
+>>> Employee.objects.get(pk=42)
Traceback (most recent call last):
...
DoesNotExist: Employee matching query does not exist.
# Use the name of the primary key, rather than pk.
->>> Employee.objects.get(employee_code__exact='ABC123')
+>>> Employee.objects.get(employee_code__exact=123)
<Employee: Dan Jones>
# pk can be used as a substitute for the primary key.
->>> Employee.objects.filter(pk__in=['ABC123','XYZ456'])
+>>> Employee.objects.filter(pk__in=[123, 456])
[<Employee: Fran Bones>, <Employee: Dan Jones>]
# The primary key can be accessed via the pk property on the model.
->>> e = Employee.objects.get(pk='ABC123')
+>>> e = Employee.objects.get(pk=123)
>>> e.pk
-u'ABC123'
+123
# Or we can use the real attribute name for the primary key:
>>> e.employee_code
-u'ABC123'
+123
# Fran got married and changed her last name.
->>> fran = Employee.objects.get(pk='XYZ456')
+>>> fran = Employee.objects.get(pk=456)
>>> fran.last_name = 'Jones'
>>> fran.save()
>>> Employee.objects.filter(last_name__exact='Jones')
[<Employee: Dan Jones>, <Employee: Fran Jones>]
->>> emps = Employee.objects.in_bulk(['ABC123', 'XYZ456'])
->>> emps['ABC123']
+>>> emps = Employee.objects.in_bulk([123, 456])
+>>> emps[123]
<Employee: Dan Jones>
>>> b = Business(name='Sears')
@@ -96,15 +96,52 @@ u'ABC123'
>>> Employee.objects.filter(business__pk='Sears')
[<Employee: Dan Jones>, <Employee: Fran Jones>]
->>> Business.objects.filter(employees__employee_code__exact='ABC123')
+>>> Business.objects.filter(employees__employee_code__exact=123)
[<Business: Sears>]
->>> Business.objects.filter(employees__pk='ABC123')
+>>> Business.objects.filter(employees__pk=123)
[<Business: Sears>]
>>> Business.objects.filter(employees__first_name__startswith='Fran')
[<Business: Sears>]
# Primary key may be unicode string
->>> emp = Employee(employee_code='jaźń')
->>> emp.save()
+>>> bus = Business(name=u'jaźń')
+>>> bus.save()
+
+# The primary key must also obviously be unique, so trying to create a new
+# object with the same primary key will fail.
+>>> try:
+... sid = transaction.savepoint()
+... Employee.objects.create(employee_code=123, first_name='Fred', last_name='Jones')
+... transaction.savepoint_commit(sid)
+... except Exception, e:
+... if isinstance(e, IntegrityError):
+... transaction.savepoint_rollback(sid)
+... print "Pass"
+... else:
+... print "Fail with %s" % type(e)
+Pass
"""}
+
+# SQLite lets objects be saved with an empty primary key, even though an
+# integer is expected. So we can't check for an error being raised in that case
+# for SQLite. Remove it from the suite for this next bit.
+if settings.DATABASE_ENGINE != 'sqlite3':
+ __test__["API_TESTS"] += """
+# The primary key must be specified, so an error is raised if you try to create
+# an object without it.
+>>> try:
+... sid = transaction.savepoint()
+... Employee.objects.create(first_name='Tom', last_name='Smith')
+... print 'hello'
+... transaction.savepoint_commit(sid)
+... print 'hello2'
+... except Exception, e:
+... if isinstance(e, IntegrityError):
+... transaction.savepoint_rollback(sid)
+... print "Pass"
+... else:
+... print "Fail with %s" % type(e)
+Pass
+
+"""
diff --git a/tests/modeltests/get_or_create/models.py b/tests/modeltests/get_or_create/models.py
index f0faf54002..56baa5c1ed 100644
--- a/tests/modeltests/get_or_create/models.py
+++ b/tests/modeltests/get_or_create/models.py
@@ -16,6 +16,10 @@ class Person(models.Model):
def __unicode__(self):
return u'%s %s' % (self.first_name, self.last_name)
+class ManualPrimaryKeyTest(models.Model):
+ id = models.IntegerField(primary_key=True)
+ data = models.CharField(max_length=100)
+
__test__ = {'API_TESTS':"""
# Acting as a divine being, create an Person.
>>> from datetime import date
@@ -61,4 +65,19 @@ False
... else:
... print "Fail with %s" % type(e)
Pass
+
+# If you specify an existing primary key, but different other fields, then you
+# will get an error and data will not be updated.
+>>> m = ManualPrimaryKeyTest(id=1, data='Original')
+>>> m.save()
+>>> try:
+... m, created = ManualPrimaryKeyTest.objects.get_or_create(id=1, data='Different')
+... except Exception, e:
+... if isinstance(e, IntegrityError):
+... print "Pass"
+... else:
+... print "Fail with %s" % type(e)
+Pass
+>>> ManualPrimaryKeyTest.objects.get(id=1).data == 'Original'
+True
"""}