Django unique = True不工作

时间:2013-07-13 06:17:58

标签: python django

这是来自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

这是我的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 shell中,我可以自由地执行此操作:

>>> 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's (auto incrementing fields).

我正在使用mysql,django 1.5。有没有人知道可能导致这种情况的原因?

我正在使用自定义管理器,但我怀疑这是问题。

感谢。

3 个答案:

答案 0 :(得分:39)

对于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。)

答案 1 :(得分:1)

可以避免直接在db上运行sql脚本。而是在迁移中添加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),
    ]

答案 2 :(得分:0)

解决方案非常简单,只需按照他们的步骤操作即可。

1 - Dell all the files in the migration folder
2 - Then run the command "python manage.py makemigrations"
3 - Then run the command "python manage.py migrate"

OR

借助一个简单的SQL-lite查询添加索引示例进行操作

alter table test add index index_name(col1(255),col2(255));

添加唯一索引示例

alter table test add unique index_name(col1(255),col2(255));