Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/73.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql Django:使auth_user.email不区分大小写且唯一且可为空_Sql_Django_Sqlite_Unit Testing_Django Models - Fatal编程技术网

Sql Django:使auth_user.email不区分大小写且唯一且可为空

Sql Django:使auth_user.email不区分大小写且唯一且可为空,sql,django,sqlite,unit-testing,django-models,Sql,Django,Sqlite,Unit Testing,Django Models,我想使auth_user.email不区分大小写,是唯一的、可空的和默认空的。以下几点几乎奏效: from django.db.models.signals import post_syncdb import app.models SQLITE_AUTH_REFORM = [ "PRAGMA writable_schema = 1;", """UPDATE SQLITE_MASTER SET SQL = 'CREATE TABLE auth_user ( "id" integer NO

我想使
auth_user.email
不区分大小写,是唯一的、可空的和默认空的。以下几点几乎奏效:

from django.db.models.signals import post_syncdb
import app.models

SQLITE_AUTH_REFORM = [
"PRAGMA writable_schema = 1;",
"""UPDATE SQLITE_MASTER SET SQL =
'CREATE TABLE auth_user (
    "id" integer NOT NULL PRIMARY KEY,
    "username" varchar(30) NOT NULL UNIQUE,
    "first_name" varchar(30) NOT NULL,
    "last_name" varchar(30) NOT NULL,
    "email" varchar(75) DEFAULT NULL,
    "password" varchar(128) NOT NULL,
    "is_staff" bool NOT NULL,
    "is_active" bool NOT NULL,
    "is_superuser" bool NOT NULL,
    "last_login" datetime NOT NULL,
    "date_joined" datetime NOT NULL
)' WHERE NAME = 'auth_user';""",
"PRAGMA writable_schema = 0;",
]

def post_syncdb_callback(sender, **kwargs):
    from django.db import connections
    from django.conf import settings
    cursor = connections['default'].cursor()

    if 'sqlite' in settings.DATABASES['default']['ENGINE']:
        for stmt in SQLITE_AUTH_REFORM:
            cursor.execute(stmt)
        cursor.execute(
            "CREATE UNIQUE INDEX IF NOT EXISTS auth_user_email_unique "
            "ON auth_user (email COLLATE NOCASE);"
        )
    else:  # Oracle
        cursor.execute(
            "CREATE UNIQUE INDEX auth_user_email_unique "
            "ON auth_user (upper(email));"
        )
    cursor.cursor.close()

post_syncdb.connect(post_syncdb_callback, sender=app.models)
我能

让我心满意足。而且

User.objects.create(username=str(random.random()), email='Foo')
User.objects.create(username=str(random.random()), email='foo')
...
IntegrityError: column email is not unique
唯一的问题是
默认NULL
似乎不起作用:
User.objects.create(username=str(random.random())
创建一个带有空字符串电子邮件的用户

但是,在单元测试中,我相信有什么事情会阻止post syncdb钩子工作:

class DjangoUserTest(TestCase):

    def test_unique_nullable_email(self):
        import IPython; IPython.embed()
        u1 = User.objects.create(username="u1", email=None)
        u2 = User.objects.create(username="u2", email=None)
我可以进入ipython外壳,看到表已明显修改:

In [1]: from django.db import connection

In [2]: c = connection.cursor()

In [3]: r = c.execute("select `sql` from sqlite_master WHERE tbl_name = 'auth_user';")

In [4]: r.fetchall()
Out[4]: 
[(u'CREATE TABLE auth_user (\n    "id" integer NOT NULL PRIMARY KEY,\n    "username" varchar(30) NOT NULL UNIQUE,\n    "first_name" varchar(30) NOT NULL,\n    "last_name" varchar(30) NOT NULL,\n    "email" varchar(75) DEFAULT NULL,\n    "password" varchar(128) NOT NULL,\n    "is_staff" bool NOT NULL,\n    "is_active" bool NOT NULL,\n    "is_superuser" bool NOT NULL,\n    "last_login" datetime NOT NULL,\n    "date_joined" datetime NOT NULL\n)',),
 (None,),
 (u'CREATE UNIQUE INDEX auth_user_email_unique ON auth_user (email COLLATE NOCASE)',)]
但是,在尝试创建时,我得到,
IntegrityError:auth_user.email可能不为NULL
。当
从sqlite_master选择sql,其中tbl_name='auth_user'时,这是如何发生的
清楚地表示
“email”varchar(75)默认为NULL
。我觉得我只需要提交post_syncdb之类的东西。有什么想法吗


更新:没有任何
connection.commit()
cursor.close()
帮助,使用
TransactionTestCase
没有帮助。

您需要在django 1.5中使用可配置的用户模型选项-这是正确的方法。hmmm。。您必须更改django.contrib.auth中的模型,这是非常不推荐的。但是,同步后挂钩在单元测试之前运行,看起来该字段可以为空
In [1]: from django.db import connection

In [2]: c = connection.cursor()

In [3]: r = c.execute("select `sql` from sqlite_master WHERE tbl_name = 'auth_user';")

In [4]: r.fetchall()
Out[4]: 
[(u'CREATE TABLE auth_user (\n    "id" integer NOT NULL PRIMARY KEY,\n    "username" varchar(30) NOT NULL UNIQUE,\n    "first_name" varchar(30) NOT NULL,\n    "last_name" varchar(30) NOT NULL,\n    "email" varchar(75) DEFAULT NULL,\n    "password" varchar(128) NOT NULL,\n    "is_staff" bool NOT NULL,\n    "is_active" bool NOT NULL,\n    "is_superuser" bool NOT NULL,\n    "last_login" datetime NOT NULL,\n    "date_joined" datetime NOT NULL\n)',),
 (None,),
 (u'CREATE UNIQUE INDEX auth_user_email_unique ON auth_user (email COLLATE NOCASE)',)]