我有一个与Django的User模型有一对一关系的Profile模型,我有另一个模型,称为Permission(与Django的内部权限概念无关),它具有Profile的外键 . 像这样:(为了简单起见,我在这里删除了大部分字段)
from django.db import models
from django.contrib.auth.models import User as DjangoUser
class Account(models.Model):
name = models.CharField(max_length=200, db_index=True)
class Profile(models.Model):
django_user = models.OneToOneField(DjangoUser)
default_account = models.ForeignKey(Account)
class Permission(models.Model):
# Which user has the permission
user = models.ForeignKey(Profile, db_index=True)
# Which account they have the permission on
account = models.ForeignKey(Account, db_index=True)
我想为Permission创建一个序列化器,它将创建如下对象:
{
"user": "me@example.com",
"account": 123
}
其中“account”的值是帐户的主键(这样很容易,我可以使用PrimaryKeyRelatedField),“user”的值是用户的电子邮件地址(这是我尚未想到的部分,因为电子邮件地址不直接存储在Profile对象上,它位于关联的DjangoUser对象上 . 另请注意,这不是只读的 - 在创建权限时,它确实需要能够从电子邮件地址反序列化为Profile对象 .
到目前为止我尝试过的一些事情,用于在Permission序列化器上表示用户...
1 .
user = serializers.RelatedField(read_only=False)
有了这个,如果我将电子邮件地址(或主键或其他任何内容)作为"user"发布,它会返回400错误,说 {"user": "This field is required."}
,好像我根本没有包含该字段 .
2 .
user = serializers.SlugRelatedField(slug_field='django_user.email')
有了这个,我得到 AttributeError: 'Profile' object has no attribute 'django_user.email'
. 如果我使用 'django_user__email'
也会发生同样的事情 .
有任何想法吗?
4 回答
根据docs:
However, there has never been a successful attempt with the dotted notation in my projects. I always ended up using an instance method or a property instead.
最近我潜入source code的
ModelSerializer
,发现了一些有趣的东西:可能处理虚线表示法遍历的部分应为
elif field_name in info.relations
.根据我项目的回溯,
field_name
可能类似于"django_user.email"
,info
是一个带有OrderedDict的relations
属性的NamedTuple .info.relations
OrderedDict的键是ForeignKey
s和ManyToManyField
的字段名称 .所以真的,虚线符号遍历不会被这个处理 .
最后,点缀符号遍历由
return self.build_unknown_field(...)
处理raised an exception .我花时间写了一些代码来更好地理解你的问题 . 如果要完全支持
PermissionsSerializer
上的CRUD操作,则需要嵌套Profile
对象,以便可以读取其属性 . 这些是我建议你实现的序列化器 .输出是:
希望这可以帮助你,如果这是方法是有用的,你想让它可写可看(http://www.django-rest-framework.org/api-guide/relations/#nested-relationships) .
根据Django REST Framework序列化程序参考(http://www.django-rest-framework.org/api-guide/fields/#core-arguments):
因此,如果
source='user.email'
无效,您可以尝试创建方法(例如get_user_email
),在source
字段中使用它并使其手动返回用户电子邮件 .你能尝试一下:
user = serializers.SlugRelatedField(slug_field='django_user__email')
?有时在Django中,双下划线表示查询可能很有用 . 资料来源:https://docs.djangoproject.com/en/1.8/topics/db/queries/#field-lookups