diff --git a/django/db/backends/__init__.py b/django/db/backends/__init__.py
index ebe8875..a94a2f7 100644
a
|
b
|
class BaseDatabaseOperations(object):
|
762 | 762 | # need not necessarily be implemented using "LIKE" in the backend. |
763 | 763 | prep_for_iexact_query = prep_for_like_query |
764 | 764 | |
| 765 | def validate_autopk_value(self, value): |
| 766 | """ |
| 767 | Certain backends does not accept certain values for primary key |
| 768 | (for example zero in MySQL). It raises ValueError if value is invalid |
| 769 | otherwise it returns validated value. |
| 770 | """ |
| 771 | return value |
| 772 | |
765 | 773 | def value_to_db_date(self, value): |
766 | 774 | """ |
767 | 775 | Transform a date value to an object compatible with what is expected |
diff --git a/django/db/backends/mysql/base.py b/django/db/backends/mysql/base.py
index 830808b..089d72e 100644
a
|
b
|
class DatabaseOperations(BaseDatabaseOperations):
|
257 | 257 | else: |
258 | 258 | return [] |
259 | 259 | |
| 260 | def validate_autopk_value(self, value): |
| 261 | if value == 0: |
| 262 | raise ValueError('The database backend does not accept %s as a ' |
| 263 | 'value for primary key field.' % (value,)) |
| 264 | return value |
| 265 | |
260 | 266 | def value_to_db_datetime(self, value): |
261 | 267 | if value is None: |
262 | 268 | return None |
diff --git a/django/db/models/fields/__init__.py b/django/db/models/fields/__init__.py
index 22546c2..f85ce4b 100644
a
|
b
|
class AutoField(Field):
|
531 | 531 | def validate(self, value, model_instance): |
532 | 532 | pass |
533 | 533 | |
| 534 | def get_db_prep_value(self, value, connection, prepared=False): |
| 535 | if not prepared: |
| 536 | value = self.get_prep_value(value) |
| 537 | value = connection.ops.validate_autopk_value(value) |
| 538 | return value |
| 539 | |
534 | 540 | def get_prep_value(self, value): |
535 | 541 | if value is None: |
536 | 542 | return None |
diff --git a/tests/regressiontests/backends/tests.py b/tests/regressiontests/backends/tests.py
index cfb662e..0c660e5 100644
a
|
b
|
from django.db import (backend, connection, connections, DEFAULT_DB_ALIAS,
|
13 | 13 | from django.db.backends.signals import connection_created |
14 | 14 | from django.db.backends.postgresql_psycopg2 import version as pg_version |
15 | 15 | from django.db.utils import ConnectionHandler, DatabaseError, load_backend |
16 | | from django.test import TestCase, skipUnlessDBFeature, TransactionTestCase |
| 16 | from django.test import (TestCase, skipUnlessDBFeature, skipIfDBFeature, |
| 17 | TransactionTestCase) |
17 | 18 | from django.test.utils import override_settings |
18 | 19 | from django.utils import unittest |
19 | | |
20 | 20 | from . import models |
21 | 21 | |
22 | 22 | |
… |
… |
class BackendLoadingTests(TestCase):
|
618 | 618 | self.assertRaisesRegexp(ImproperlyConfigured, |
619 | 619 | "Try using django.db.backends.sqlite3 instead", |
620 | 620 | load_backend, 'sqlite3') |
| 621 | |
| 622 | |
| 623 | class MySQLPKZeroTests(TestCase): |
| 624 | """ |
| 625 | Zero as id for autofield should raise exception in MySQL, because MySQL |
| 626 | handles zero in a specific way. |
| 627 | """ |
| 628 | |
| 629 | @skipIfDBFeature('allows_primary_key_0') |
| 630 | def test_zero_as_autoval(self): |
| 631 | with self.assertRaises(ValueError): |
| 632 | models.Square.objects.create(id=0, root=0, square=1) |
| 633 | No newline at end of file |