2014-10-02 111 views
8

我有一个配置文件模型,它与Django的用户模型有一对一的关系,我有另一个模型,名为权限(与Django的内部权限无关),有一个配置文件的外键。像这样的:(我已经删除大多数字段在这里,为了简单起见)Django REST框架:间接相关属性的SlugRelatedField?

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) 

我想为许可串行,这将创建一个这样的对象:

{ 
    "user": "[email protected]", 
    "account": 123 
} 

其中值“account”是账户的主键(这很简单,我可以使用PrimaryKeyRelatedField),“user”的值是用户的电子邮件地址(这是我还没有弄清楚的部分,因为电子邮件地址是不直接存储在Profile对象上,它在关联的DjangoUser对象上)。还要注意,这不是只读的 - 创建权限时,它需要能够将电子邮件地址反序列化为Profile对象。

有些事情到目前为止,我已经试过了,为表示对权限串行用户...

1.

user = serializers.RelatedField(read_only=False) 

有了这一个,如果我发布的电子邮件地址(或主键或其他任何东西)作为“用户”,它返回一个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'

任何想法?

回答

0

我花时间写了一些代码,以更好地理解你的问题。如果您想在您的PermissionsSerializer上完全支持CRUD操作,则需要嵌套Profile对象,以便您可以读取其属性。 这些是我建议你实现的序列化器。

from django.contrib.auth.models import User 
from rest_framework import serializers 
from .models import Permission, Profile, Account 


class UserSerializer(serializers.ModelSerializer): 
    class Meta: 
     model = User 
     fields = ('username', 'email',) 


class ProfileSerializer(serializers.ModelSerializer): 

    django_user = UserSerializer(many=False) 

    class Meta: 
     model = Profile 
     fields = ('django_user',) 


class PermissionSerializer(serializers.ModelSerializer): 

    user = ProfileSerializer(many=False) 

    class Meta: 
     model = Permission 
     fields = ('user', 'account') 

,输出是:

{ 
     "user": { 
      "django_user": { 
       "username": "admin", 
       "email": "[email protected]" 
      } 
     }, 
     "account": 1 
    } 

希望这可以帮助你,如果是这样的方法是有用的,你想让它写能看(http://www.django-rest-framework.org/api-guide/relations/#nested-relationships)。

2

根据Django的REST框架串行器参考(http://www.django-rest-framework.org/api-guide/fields/#core-arguments):

将被用于填充字段的属性的名称。可能是只接受自我参数的方法,如URLField(source ='get_absolute_url'),或者可能使用虚线符号来遍历属性,如EmailField(source ='user.email')。

因此,如果source='user.email'不起作用,您可以尝试创建一个方法(例如,get_user_email),在source字段中使用它,并使其手动返回用户电子邮件。

+0

正如原始问题中所述,该字段不是只读的。它需要能够反序列化,而不仅仅是序列化。 – Avril 2016-01-18 00:33:32

+0

使用'source'并不意味着它是只读的。当您尝试反序列化时会发生什么? – 2016-01-18 16:47:19

相关问题