我使用django-mongodb-engine制作网站。
我有一个自定义用户模型,如下所示:
class User(AbstractUser):
trigrama = models.CharField(max_length=3, unique=True)
external_email = models.EmailField(unique=True)
phone_number = models.CharField(max_length=20, unique=True)
AbstractUser._meta.get_field_by_name('email')[0]._unique=True
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = [
'first_name', 'last_name', 'trigrama',
'external_email', 'phone_number', 'username'
]
它工作正常,但后来我尝试将嵌入文档添加到用户模型中:
permissions = EmbeddedModelField('Permission')
Permission
是一个如下所示的类:
class Permission(models.Model):
computers = ListField(EmbeddedModelField('Computer'))
projects = ListField(EmbeddedModelField('Project'))
scripts = ListField(EmbeddedModelField('Script'))
现在,当我尝试使用User.objects.create()
在shell中创建用户时,我收到以下错误:
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "C:\Python27\lib\site-packages\django\db\models\manager.py", line 149, in create
return self.get_query_set().create(**kwargs)
File "C:\Python27\lib\site-packages\django\db\models\query.py", line 416, in create
obj.save(force_insert=True, using=self.db)
File "C:\Python27\lib\site-packages\django\db\models\base.py", line 548, in save
force_update=force_update, update_fields=update_fields)
File "C:\Python27\lib\site-packages\django\db\models\base.py", line 668, in save_base
result = manager._insert([self], fields=fields, return_id=update_pk, using=using, raw=raw)
File "C:\Python27\lib\site-packages\django\db\models\manager.py", line 215, in _insert
return insert_query(self.model, objs, fields, **kwargs)
File "C:\Python27\lib\site-packages\django\db\models\query.py", line 1675, in insert_query
return query.get_compiler(using=using).execute_sql(return_id)
File "C:\Python27\lib\site-packages\djangotoolbox\db\basecompiler.py", line 583, in execute_sql
"field) to None!" % field.name)
IntegrityError: You can't set permissions (a non-nullable field) to None!
我尝试使用以下内容将默认值设置为Permission()
permissions = EmbeddedModelField('Permission', default=Permission())
然后我收到以下错误:
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "C:\Python27\lib\site-packages\django\db\models\manager.py", line 149, in create
return self.get_query_set().create(**kwargs)
File "C:\Python27\lib\site-packages\django\db\models\query.py", line 416, in create
obj.save(force_insert=True, using=self.db)
File "C:\Python27\lib\site-packages\django\db\models\base.py", line 548, in save
force_update=force_update, update_fields=update_fields)
File "C:\Python27\lib\site-packages\django\db\models\base.py", line 668, in save_base
result = manager._insert([self], fields=fields, return_id=update_pk, using=using, raw=raw)
File "C:\Python27\lib\site-packages\django\db\models\manager.py", line 215, in _insert
return insert_query(self.model, objs, fields, **kwargs)
File "C:\Python27\lib\site-packages\django\db\models\query.py", line 1675, in insert_query
return query.get_compiler(using=using).execute_sql(return_id)
File "C:\Python27\lib\site-packages\djangotoolbox\db\basecompiler.py", line 579, in execute_sql
connection=self.connection
File "C:\Python27\lib\site-packages\djangotoolbox\fields.py", line 364, in get_db_prep_save
(embedded_model, type(embedded_instance)))
TypeError: Expected instance of type <class 'users.models.Permission'>, not <type 'unicode'>.
那么我应该如何将嵌入式文档添加到自定义用户模型中呢?
P.S。
如果我在shell中键入Permission()
它实例化就好了,返回Permission object
而不是unicode。
答案 0 :(得分:3)
If you read the docs关于为字段设置默认值的方式,您会发现它希望收到一个值...或a callable object。你不能只是在那里创建实例,它不会像那样工作(强调我的):
默认值不能是可变对象(模型实例,列表,集, 等),作为对该对象的同一实例的引用 用作所有新模型实例中的默认值。
当你自己调用它时(即Permission()
)你得到的是一个实例,它反过来又返回一个unicode(它调用__unicode__
函数)。
换句话说,只需删除尾随()
:
permissions = EmbeddedModelField('Permission', default=Permission)
现在,说实话,这可能会有问题,因为它实际上并没有保存新的权限对象,整个事情可能会变得混乱(这是权限和所有,你想要的要格外小心)。因此,创建一个包装操作的函数可能会更好,并使用它来代替:
def get_initial_perms():
p = Permission()
p.save()
return p
# later:
permissions = EmbeddedModelField('Permission', default=get_initial_perms)
类似的解决方案是覆盖save()
方法并在调用实际save
部分之前为对象提供权限。