在单个get()请求中显示两个相关模型

时间:2017-11-08 07:03:15

标签: python django django-rest-framework

我有两个与user_id相互关联的模型,现在我想要一个get请求,我将在这两个表中包含字段。如何使这成为可能?我想这可以用foreign key,但我该如何实现呢。

两个模型看起来像:

MODEL1

class Account(AbstractBaseUser):
    fullname = models.CharField(max_length=100, blank=True)
    username = models.CharField(unique=True, max_length=50)
    email = models.EmailField(unique=True)
    phonenumber = models.IntegerField(null=True)
    date_created = models.DateTimeField(auto_now_add=True)
    date_modified = models.DateTimeField(auto_now=True)
    is_admin = models.BooleanField(default=False)
    objects = AccountManager()
    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = ['username']

models2

class Profile(models.Model):
    User = get_user_model()
    branch = models.CharField(max_length=20, null=True)
    year = models.IntegerField(null=True)
    image = models.ImageField(upload_to="accounts/images/", null=True, blank=True)
    user = models.OneToOneField(
        User,
        on_delete=models.CASCADE,
        primary_key=False,
        null=True
    )

我想根据目前登录的用户显示特定的用户详细信息。

我的get请求看起来像这样:

def get(self, request, format=None):
        current_user = request.user
        acc = Account.objects.filter(pk=current_user.pk)
        serializer = AccountSerializer(acc, many=True)
        return Response(serializer.data)

但是这只显示Account模型的数据,我也想要Profile模型的数据。我该怎么做?

更新

串行

class AccountSerializer(serializers.ModelSerializer):
    password = serializers.CharField(write_only=True, required=True)
    token = serializers.CharField(max_length=500, read_only=True)

    class Meta:
        model = Account
        fields = (
        'id', 'email', 'username', 'date_created', 'date_modified',
        'fullname', 'password','phonenumber' ,'token' )
        read_only_fields = ('date_created', 'date_modified')

    def create(self, validated_data):
        return Account.objects.create_user(**validated_data)

    def update(self, instance, validated_data):
        instance.email = validated_data.get('email', instance.email)
        instance.username = validated_data.get('username',
        instance.username)
        instance.fullname = validated_data.get('fullname',
        instance.fullname)
        password = validated_data.get('password', None)
        instance.save()
        return instance

UPDATE2

在获得要求之后,我想要类似的东西:

{
   "username": "Steve"
   "fullname": "Steve Smith"
   "phonenumber": "1234567890"
   "email": "st@gmail.com"
   "profile":[ {
    "branch": "CS"
    "year": 4
    "image": path/to/folder
   }]
}

2 个答案:

答案 0 :(得分:1)

class ProfileSerializer(ModelSerializer):
    user = AccountSerializer(read_only=True)

    class Meta:
        model = Profile
        fields = '__all__'


def get(self, request, format=None):
        try:
            profile= Profile.objects.get(user=request.user)
        except Profile.DoseNotExist:
            return Response('404')
        serializer = ProfileSerializer(profile)
        return Response(serializer.data)

这将返回如下数据:

{
   "your profile fields": "xxx"
   ...
   "user": {
    "your user fields": "xxx"
    ...
   }
}

如果您希望您的用户信息包含个人资料信息:

class AccountSerializer(serializers.ModelSerializer):
    password = serializers.CharField(write_only=True, required=True)
    token = serializers.CharField(max_length=500, read_only=True)
    profile = serializers.SerializerMethodField()

    class Meta:
        model = Account
        fields = (
        'id', 'email', 'username', 'date_created', 'date_modified',
        'fullname', 'password','phonenumber' ,'token' )
        read_only_fields = ('date_created', 'date_modified')

    def create(self, validated_data):
        ...

    def update(self, instance, validated_data):
        ...

    def get_profile(self, instance):
        try:
            profile= Profile.objects.get(user=instance)
            return ProfileSerializer(profile).data
        except Profile.DoseNotExist:
                return ''

或:

class AccountSerializer(serializers.ModelSerializer):
    password = serializers.CharField(write_only=True, required=True)
    token = serializers.CharField(max_length=500, read_only=True)
    profile = serializers.ProfileSerializer(read_only=True)

    class Meta:
        model = Account
        fields = (
        'id', 'email', 'username', 'date_created', 'date_modified',
        'fullname', 'password','phonenumber' ,'token' )
        read_only_fields = ('date_created', 'date_modified')

    def create(self, validated_data):
        ...

    def update(self, instance, validated_data):
        ...

这将返回:

{
   "username": "Steve"
   "fullname": "Steve Smith"
   "phonenumber": "1234567890"
   "email": "st@gmail.com"
   "profile":{
    "branch": "CS"
    "year": 4
    "image": path/to/folder
   }
}

因为你的个人资料是用户的,所以个人资料是JsonObject而不是JsonArray

答案 1 :(得分:0)

将您的AccountSerializer配置为这样,

class ProfileSerializer(serializers.ModelSerializer):        
    class Meta:
        model = Profile
        fields = [f.name for f in model._meta.fields]

class AccountSerializer(serializers.ModelSerializer):
    password = serializers.CharField(write_only=True, required=True)
    token = serializers.CharField(max_length=500, read_only=True)
    profile = ProfileSerializer()
    class Meta:
        model = Account
        fields = [f.name for f in model._meta.fields]

您也可以相应地覆盖序列化工具的createupdate方法。