为什么没有auth.User检查必填字段?

时间:2011-12-11 13:14:33

标签: python django django-models

在阅读this问题后,我想扩展django的auth.User,
这是我的models.py:

from django.db import models
from django.contrib.auth.models import User
from django.db.models.signals import post_save  

class UserProfile(models.Model):
    user = models.OneToOneField(User)
    age = models.SmallIntegerField()  

def create_user_profile(sender, instance, created, **kwargs):  
    if created:  
        profile, created = UserProfile.objects.get_or_create(user=instance)    

post_save.connect(create_user_profile, sender=User) 

我在settings.py:

的底部添加了这一行
AUTH_PROFILE_MODULE = 'MYAPP.UserProfile'  

问题是,当我运行python manage.py shell并输入:

from django.contrib.auth.models import User  
user = User()  

它没有问题!为什么不给出错误,我没有给出username/password

3 个答案:

答案 0 :(得分:6)

当您运行user = User()时,您所做的只是创建一个新的User实例。在您尝试使用user.save()保存错误之前,它不会引发错误。

要同时创建新模型实例并将其保存到DB:

user = User.objects.create() # should throw an IntegrityError due to required (not NULL) fields not provided

答案 1 :(得分:0)

请确保UserProfile位于MYAPP中的models.py内,并且MYAPP已在INSTALLED_APPS中注册。看起来你的信号根本不起作用。如果它没有帮助,请在shell中尝试:

from django.contrib.auth.models import User  
from MYAPP.models import UserProfile  
user = User() 

因此,您将确保信号已正确注册。

答案 2 :(得分:0)

这些限制主要用于表单验证;使用API​​时强制执行的限制很少(主要是可能导致数据库问题的限制)。

您可以轻松创建一个空用户(没有用户名的用户):

>>> from django.contrib.auth.models import User
>>> u = User()
>>> u.save()
>>> u
<User: >
>>> u.id
2

但是,如果您尝试创建两个空用户,则会获得IntegrityError

>>> u = User()
>>> u.save()
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/Users/burhan/work/projects/foo/env/lib/python2.7/site-packages/django/db/models/base.py", line 460, in save
    self.save_base(using=using, force_insert=force_insert, force_update=force_update)
  File "/Users/burhan/work/projects/foo/env/lib/python2.7/site-packages/django/db/models/base.py", line 553, in save_base
    result = manager._insert(values, return_id=update_pk, using=using)
  File "/Users/burhan/work/projects/foo/env/lib/python2.7/site-packages/django/db/models/manager.py", line 195, in _insert
    return insert_query(self.model, values, **kwargs)
  File "/Users/burhan/work/projects/foo/env/lib/python2.7/site-packages/django/db/models/query.py", line 1436, in insert_query
    return query.get_compiler(using=using).execute_sql(return_id)
  File "/Users/burhan/work/projects/foo/env/lib/python2.7/site-packages/django/db/models/sql/compiler.py", line 791, in execute_sql
    cursor = super(SQLInsertCompiler, self).execute_sql(None)
  File "/Users/burhan/work/projects/foo/env/lib/python2.7/site-packages/django/db/models/sql/compiler.py", line 735, in execute_sql
    cursor.execute(sql, params)
  File "/Users/burhan/work/projects/foo/env/lib/python2.7/site-packages/django/db/backends/util.py", line 34, in execute
    return self.cursor.execute(sql, params)
  File "/Users/burhan/work/projects/foo/env/lib/python2.7/site-packages/django/db/backends/sqlite3/base.py", line 234, in execute
    return Database.Cursor.execute(self, query, params)
IntegrityError: column username is not unique

如果查看模型,您会看到username字段(unique=True)上存在数据库级限制:

`username = models.CharField(_('username'), max_length=30, unique=True...`

这是在API级别强制执行的,因此您不能让两个用户具有相同的username字段。

另一个例子是choices参数。这主要用于演示。如果您的字段为choices=('M','Male'),('F','Female');使用API​​,您可以插入任何单个字符,它会很乐意接受它。

在数据库级别强制执行的选项(意思是,您不能从API中“违反”它们):

  1. unique
  2. max_length
  3. null(不要与blank混淆)