Skip to main content
 首页 » 编程设计

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

2024年12月31日18tintown

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

User model and Consumer has one to one relationship and Consumer and Task has one to many relationship.

我的 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'] 

现在我想做的是,每当我保存一个任务的帖子时,它应该保存任务并将自己关联到当前的消费者。

可以做什么。

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

 serializer.save(user=request.user) 

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

我想知道是否有更好的方法来做到这一点?我是 DRF 的新手并且很难学习它。

请您参考如下方法:

您可以使用 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__) 

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

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

class TaskSerializer(serializers.ModelSerializer): 
 
    consumer=serializers.HiddenField(default=CurrentConsumerDefault()) 
 
    class Meta: 
        model=Tasks 
        fields=['title','description', 'consumer'] 

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