Django unique = True не работает
Это из документации django:
Field.unique
Если True, это поле должно быть уникальным по всей таблице.
Это выполняется на уровне базы данных и путем проверки модели. Если вы попытаетесь сохранить модель с двойным значением в уникальном поле, django.db.IntegrityError будет поднят методом save().
Вот мои models.py
class MyModel(models.Model):
# my pk is an auto-incrementing field
url = models.URLField("URL", unique=True)
text = models.TextField(max_length=1000)
# my model is just two fields, one pk (unique), and another unique field,
#, the url
Здесь мой is manage.py sqlall (я запустил syncdb)
CREATE TABLE `MyModel_mymodel` (
`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY,
`url` varchar(200) NOT NULL UNIQUE,
`text` varchar(1000) NOT NULL,
Однако в оболочке manage.py я могу свободно это делать:
>>> from MyModel.models import MyModel
>>> MyModel().save() # it works fine!? Not even the text was checked for!
>>> MyModel(url="blah").save()
>>> MyModel(url="blah").save() # it still works!
# I checked the mysql database afterwards, the models were saved just fine, they
# however did have different PK (auto incrementing fields).
Я использую mysql, django 1.5. Кто-нибудь есть идея, что может быть причиной этого?
Я использую настраиваемый менеджер, но я сомневаюсь, что проблема.
Спасибо.
Ответы
Ответ 1
Для django 1.9 +
Выполняя makemigrations
, тогда migrate
применяет уникальное ограничение к sqlite3
Для django < 1,9
Поскольку вы используете django 1.5, это решение будет применяться.
Если вы добавили unique=True
после того, как таблица уже была создана, то даже если вы сделаете syncdb
позже, уникальное условие не будет добавлено в вашу таблицу.
Я могу подтвердить с помощью sqlite3
, что Django 1.5 с радостью сохраняет повторяющиеся объекты с MyModel(url="blah").save()
, если в базе данных не существует уникального ограничения, которое, похоже, противоречит документам.
Лучшим решением для вас является создание ограничения вручную в вашей базе данных с помощью этой команды.
ALTER TABLE MyModel_mymodel ADD UNIQUE (url);
Или, если вы не возражаете, вы можете воссоздать свою таблицу. (Отбросьте таблицу, а затем запустите syncdb
.)
Ответ 2
Можно запускать скрипты sql непосредственно на db. Скорее добавьте выполнение sql в вашу миграцию:
from __future__ import unicode_literals
from django.db import migrations, connection
def alter_table(apps, schema_editor):
query ="ALTER TABLE <your table> ADD UNIQUE (unique_col);"
cursor = connection.cursor()
cursor.execute(query)
cursor.close()
class Migration(migrations.Migration):
dependencies = [
('app', 'yourlastmigration'),
]
operations = [
migrations.RunPython(alter_table),
]