gpt4 book ai didi

python - DRF - 编写双嵌套序列化程序的更好方法

转载 作者:行者123 更新时间:2023-12-04 17:35:20 34 4
gpt4 key购买 nike

我正在构建一个 todo 应用程序,可以在 todo 上发布评论。
为此,我制作了一个可写的双嵌套序列化程序。它有效,但我编写的更新方法难以理解,因此我试图使其更具可读性。是否有更好的(或标准的)方法来为双嵌套序列化程序编写更新方法?

我已经阅读了官方文档中嵌套序列化程序的文档。 https://www.django-rest-framework.org/api-guide/serializers/

模型.py

class CustomUser(AbstractUser):

def __str__(self):
return self.email


class Todo(models.Model):
publisher = models.ForeignKey(
CustomUser,
on_delete=models.CASCADE,
related_name="todos",
)
title = models.CharField(max_length=50)
pub_date = models.DateTimeField('date published')
description = models.CharField(max_length=800)
is_done = models.BooleanField(default=False)

def __str__(self):
return self.title


class Comment(models.Model):
subject = models.ForeignKey(
Todo,
on_delete=models.CASCADE,
related_name="comments",
)
publisher = models.ForeignKey(CustomUser, on_delete=models.CASCADE)
title = models.CharField(max_length=50, default=None)
pub_date = models.DateTimeField('date published')
description = models.CharField(max_length=800)

def __str__(self):
return self.description


序列化程序.py
class CommentSerializer(serializers.ModelSerializer):
class Meta:
model = Comment
fields = (
'url',
'title',
'pub_date',
'description',
)
read_only_fields = (
'url',
'pub_date',
)


class TodoSerializer(serializers.ModelSerializer):
comments = CommentSerializer(required=False, many=True)

class Meta:
model = Todo
fields = (
'url',
'title',
'pub_date',
'description',
'is_done',
'comments'
)
read_only_fields = (
'url',
'pub_date',
)


class UserSerializer(serializers.ModelSerializer):
todos = TodoSerializer(required=False, many=True)

class Meta:
model = CustomUser
fields = (
'url',
'email',
'username',
'todos',
)
read_only_fields = (
'url',
'email',
)

def create(self, validated_data):
todos = validated_data.pop('todos', None)
user = CustomUser.objects.create(**validated_data)

if todos is not None:
for todo in todos:
comments = todo.pop('comments', None)
Todo.objects.create(user=user, **todo)
if comments is not None:
for comment in comments:
Comment.objects.create(todo=todo, **comment)
return user

def update(self, instance, validated_data):
todos_data = validated_data.pop('todos', None)
todos = (instance.todos).all()
todos = list(todos)
instance.username = validated_data.get('username', instance.username)
instance.save()
if todos_data is not None:
for todo_data in todos_data:
comments_data = todo_data.pop('comments')
todo = todos.pop(0)
comments = (todo.comments).all()
comments = list(comments)

todo.title = todo_data.get('title', todo.title)
todo.description = todo_data.get('description', todo.description)
todo.is_done = todo_data.get('is_done', todo.is_done)
todo.save()
if comments_data is not None:
for comment_data in comments_data:
comment = comments.pop(0)
comment.title = comment_data.get('title', comment.title)
comment.description = comment_data.get('description', comment.description)
comment.save()
return instance

预期的 JSON
{
"url": "http://127.0.0.1:8000/api/users/4/",
"email": "api01@example.com",
"username": "api01",
"todos": [
{
"url": "http://127.0.0.1:8000/api/todo/1/",
"title": "first todo1.1",
"pub_date": "2019-07-04T12:40:56.799308+09:00",
"description": "description for first todo1.1",
"is_done": true,
"comments": [
{
"url": "http://127.0.0.1:8000/api/comment/1/",
"title": "first comment-1.1",
"pub_date": "2019-07-03T12:32:26.604598+09:00",
"description": "aaaaaaaaa-1.1"
},
{
"url": "http://127.0.0.1:8000/api/comment/2/",
"title": "second comment-1.1",
"pub_date": "2019-07-03T12:56:22.906482+09:00",
"description": "bbbbbbbbbbb-1.1"
}
]
}
]
}

最佳答案

创建模型应该是各个序列化程序的责任。所以TodoSerializer应该只创建 Todo 对象和 CommentSerializer应该创建 Comment 对象。更新也一样

也不需要调用Model.objects.create(**data) .序列化程序可以自己完成。您只需要调用 super().create(validated_data)super().update(instance, validated_data) .

class TodoSerializer(serializers.ModelSerializer):

comments = serializers.ListField(child=serializers.DictField, required=True)

class Meta:
model = CustomUser
fields = (
'title',
'pub_date',
'description',
'is_done',
'comment',
)

def create(self, validated_data)
todo = super().create(validated_data)
comments = validated_data.pop('comments', [])
for comment in comments:
comment['todo'] = todo.id
serializer = CommentSerializer(data=comment)
serializer.is_valid(raise_exception=True)
serializer.save()


class AddBulkTodos(serializers.ModelSerializer):
todos = serializers.ListField(child=serializers.DictField, required=True)

class Meta:
model = CustomUser
fields = (
'url',
'email',
'username',
'todos',
)
read_only_fields = (
'url',
)

def create(self, validated_data)
todos = validated_data.pop('todos', [])
user = super().create(validated_data)
for todo in todos:
todo['user'] = user.id
serializer = TodoSerializer(data=todo)
serializer.is_valid(raise_exception=True)
serializer.save()

关于python - DRF - 编写双嵌套序列化程序的更好方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56912050/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com