简体   繁体   English

Django unique=True 不起作用

[英]Django unique=True not working

This is from django's documentation:这是来自 django 的文档:

Field.unique Field.unique

If True, this field must be unique throughout the table.如果为 True,则该字段在整个表中必须是唯一的。

This is enforced at the database level and by model validation.这是在数据库级别和模型验证中强制执行的。 If you try to save a model with a duplicate value in a unique field, a django .db.IntegrityError will be raised by the model's save() method.如果您尝试在唯一字段中保存具有重复值的模型,模型的 save() 方法将引发 django .db.IntegrityError 。

Here is my models.py这是我的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

Here my is manage.py sqlall (I ran syncdb)这是我的 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,

However, in the manage.py shell, I can freely do this:但是,在 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).

I'm using mysql, django 1.5.我正在使用 mysql、django 1.5。 Does anyone have an idea what could possible be causing this?有谁知道可能导致这种情况的原因是什么?

I am using a custom manager, but I doubt that's the issue.我正在使用自定义管理器,但我怀疑这就是问题所在。

Thanks.谢谢。

For django 1.9+对于 Django 1.9+
Running makemigrations then migrate applies the unique constraint to sqlite3运行makemigrations然后migrate将唯一约束应用于 sqlite3

For django < 1.9对于 Django < 1.9
Since you are using django 1.5, this solution will apply.由于您使用的是 django 1.5,因此此解决方案将适用。

If you added the unique=True after the table was already created, then even if you do syncdb later, the unique condition will not be added to your table.如果你在表已经创建后添加了unique=True ,那么即使你稍后执行syncdb ,唯一条件也不会添加到你的表中。

I can confirm with sqlite3 that Django 1.5 happily saves duplicate objects with MyModel(url="blah").save() if the unique constraint does not exist in the database, which seems to contradict with the docs.我可以通过sqlite3确认 Django 1.5 很乐意使用MyModel(url="blah").save()保存重复的对象,如果数据库中不存在唯一约束,这似乎与文档相矛盾。

The best solution for you is to create the constraint manually in your database using this command.最适合您的解决方案是使用此命令在数据库中手动创建约束。

ALTER TABLE MyModel_mymodel ADD UNIQUE (url);

Or if you don't mind, you can recreate your table.或者,如果您不介意,您可以重新创建您的表。 (Drop the table and then run syncdb .) (删除表,然后运行syncdb 。)

Running sql scripts directly on the db can be avoided.可以避免直接在数据库上运行 sql 脚本。 Rather add the sql execution in your migration:而是在迁移中添加 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),
    ]

The solution is pretty simple, Just follow their steps.解决方法很简单,按照他们的步骤就可以了。

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

Do it by the help of a simple SQL-lite Query Adding index Example借助一个简单的 SQL-lite 查询添加索引示例来完成

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

Adding unique index Example添加唯一索引示例

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM