Django Rest Framework-Django嵌套序列化器一对多关系

时间:2018-08-27 07:42:05

标签: python django django-rest-framework

我有三个模型:用户(django身份验证模型),消费者,任务

  

用户模型和消费者之间是一对一的关系,消费者和任务之间是一对多的关系。

我的 model.py 像这样:

class Consumer(models.Model):
    user=models.OneToOneField(User,on_delete=models.CASCADE)    
    average_rating=models.FloatField(default=5.0)

class Tasks(models.Model):

    consumer=models.ForeignKey(Consumer,on_delete=models.CASCADE,related_name='consumer_obj')
    title=models.CharField(max_length=50)
    description=models.CharField(max_length=200)
    added_on=models.DateTimeField(auto_now=True)

我的 serializers.py 如下:

class TaskSerializer(serializers.ModelSerializer):

    category=serializers.CharField(max_length=10)
    class Meta:
        model=Tasks
        fields=['title','description']

class UserSerializer(serializers.ModelSerializer):
    password=serializers.CharField(max_length=10,write_only=True)
    class Meta:
        model=User 
        fields=['username','password','email']


class ConsumerSerializer(serializers.ModelSerializer):
    user=UserSerializer()
    tasks=TaskSerializer(many=True,source='consumer_obj')
    class Meta:
        model=Consumer
        fields=['user','average_rating','tasks']

现在我要做的是,每当我保存一个任务后,它都应该保存该任务并将其自身关联到当前的使用者。

可以做什么。

现在,每当我在视图中调用serializer.save()时,我都可以将用户实例作为类似这样的参数传递

 serializer.save(user=request.user)

在我的序列化器create()函数中,我可以查询用户,然后在用户的帮助下查询使用者以将任务与该用户相关联。

我想知道是否还有更好的方法?我是DRF的新手,很难学习它。

1 个答案:

答案 0 :(得分:1)

您可以使用DRF对用户使用的相同方法,编写一个CurrentUserDefault之类的自定义对象,该对象将消费者对应方返回到当前已验证的用户:

from rest_framework.compat import unicode_to_repr

class CurrentConsumerDefault(object):
    def set_context(self, serializer_field):
        user = serializer_field.context['request'].user
        self.consumer = user.consumer

    def __call__(self):
        return self.consumer

    def __repr__(self):
        return unicode_to_repr('%s()' % self.__class__.__name__)

注意:您应该使用通用视图或自己提供对序列化程序的请求。

然后在您的TaskSerializer中,添加以下字段:

class TaskSerializer(serializers.ModelSerializer):

    consumer=serializers.HiddenField(default=CurrentConsumerDefault())

    class Meta:
        model=Tasks
        fields=['title','description', 'consumer']

my answer读到类似的问题以获取更多信息。