Django REST:如何在嵌套的 ModelSerializer 中 POST 和 PUT 数据
Django REST: How to POST and PUT Data in Nested ModelSerializer
我是 Django 的新手,已经获取了数据。
部分json如下:
{
"pk": 4,
"account": "user4",
"password": "5340",
"UserDatas": {
"memberAccount_id": 4,
"username": "Dylan",
"gender": true,
"score": 100,
"photo": "photos/2016/05/16/avatar.png",
"TaskDatas": [
{
"userData_id": 4,
"task_name": "make a phone call",
"task_is_group": false,
"task_time": "2015/05/18",
"task_score": 2,
"task_member_list": "",
"task_bulletin": "phone number is 1234-5678"
}
],
"FriendsDatas": [],
"ChatroomDatas": []
}
},
这是我的 models.py
class MemberAccount(models.Model):
account = models.CharField(max_length=50)
password = models.CharField(max_length=30)
def __str__(self):
return "%s : %s" % (self.account, self.password)
class UserData(models.Model):
memberAccount_id = models.OneToOneField(
MemberAccount,
on_delete=models.CASCADE,
primary_key=True,
related_name='UserDatas',
blank=True
)
username = models.CharField(max_length=30, default="")
gender = models.BooleanField()
score = models.IntegerField()
photo = models.ImageField(upload_to ="photos/%Y/%m/%d/", null=True ,blank=True)
class Meta:
unique_together = ('memberAccount_id', 'username')
order_with_respect_to = 'memberAccount_id'
def __str__(self):
return "%s : %s" % (self.memberAccount_id, self.username)
class TaskData(models.Model):
userData_id = models.ForeignKey(UserData, related_name='TaskDatas', null=True)
task_name = models.CharField(max_length=100, default="")
task_is_group = models.BooleanField()
task_time= models.CharField(max_length=30)
task_score = models.IntegerField()
task_member_list = models.CharField(max_length=100, null=True ,blank=True)
task_bulletin = models.TextField(blank=True, default='')
class Meta:
unique_together = ('userData_id', 'task_name')
order_with_respect_to = 'userData_id'
def __str__(self):
return "%s : %s" % (self.userData_id, self.task_name)
class ChatroomData(models.Model):
userdata_cid = models.ForeignKey(UserData, related_name='ChatroomDatas', null=True, blank=True)
chatroom_member = models.CharField(max_length=30)
chatroom_contents = models.TextField(blank=True, default='')
def __str__(self):
# 在Python3中使用 def __str__(self)
return "%s : %s" % (self.userdata_cid, self.chatroom_member)
class FriendsData(models.Model):
usersData_id = models.ForeignKey(UserData, related_name='FriendsDatas', null=True)
friend_name = models.CharField(max_length=30)
friend_account = models.CharField(max_length=50)
class Meta:
unique_together = ('usersData_id', 'friend_name')
order_with_respect_to = 'usersData_id'
def __str__(self):
# 在Python3中使用 def __str__(self)
return "%s : %s" % (self.usersData_id, self.friend_name)
class SubtaskData(models.Model):
taskData_id = models.ForeignKey(TaskData, related_name='SubtaskDatas', null=True)
subtask_name = models.CharField(max_length=100)
subtask_deadline = models.CharField(max_length=30)
subtask_completion= models.IntegerField()
subtask_importance = models.IntegerField()
subtask_item = models.TextField(blank=True, default='')
class Meta:
unique_together = ('taskData_id', 'subtask_name')
order_with_respect_to = 'taskData_id'
def __str__(self):
# 在Python3中使用 def __str__(self)
return "%s : %s" % (self.taskData_id, self.subtask_name)
views.py
@api_view(['GET','POST'])
def jobterm_list(request, format=None):
if request.method=="GET":
MemberAccounts =list(MemberAccount.objects.all())
serializer = MemberAccountSerializer(MemberAccounts,many=True)
return Response(serializer.data)
elif request.method == 'POST':
#print (request.body)
serializer = MemberAccountSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
else:
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
@api_view(['GET', 'PUT', 'DELETE']) #
def jobterm_detial(request,pk, format=None):
try:
member_Account = MemberAccount.objects.get(pk=pk)
except MemberAccount.DoesNotExist:
return Response(status=status.HTTP_404_NOT_FOUND)
if request.method == "GET":
serializer = MemberAccountSerializer(member_Account)
return Response(serializer.data)
elif request.method == "PUT":
serializer = MemberAccountSerializer(member_Account,data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
else:
return Response(serializer.errors,status=status.HTTP_400_BAD_REQUEST)
elif request.method == "DELETE":
member_Account.delete()
return Response(status=status.HTTP_204_NO_CONTENT)
serializer.py
class ChatroomDataSerializer(serializers.ModelSerializer):
class Meta:
model = ChatroomData
fields = ("userdata_cid", "chatroom_member", "chatroom_contents")
class TaskDataSerializer(serializers.ModelSerializer):
class Meta:
model = TaskData
fields = ("userData_id", "task_name", "task_is_group",
"task_time", "task_score", "task_member_list",
"task_bulletin")
class FriendsDataSerializer(serializers.ModelSerializer):
class Meta:
model = FriendsData
fields = ("usersData_id","friend_name","friend_account")
class UserDataSerializer(serializers.ModelSerializer):
TaskDatas = TaskDataSerializer( many = True )
FriendsDatas = FriendsDataSerializer( many = True )
ChatroomDatas = ChatroomDataSerializer( many = True )
class Meta:
model = UserData
fields = ("memberAccount_id","username","gender","score",
"photo","TaskDatas","FriendsDatas","ChatroomDatas")
class MemberAccountSerializer(serializers.ModelSerializer):
UserDatas = UserDataSerializer( required = False )
class Meta:
model = MemberAccount
fields = ("pk","account","password","UserDatas")
class SubtaskDataSerializer(serializers.ModelSerializer):
class Meta:
model = SubtaskData
fields = ("taskData_id","subtask_name","subtask_deadline","subtask_completion",
"subtask_importance","subtask_item")
我尝试在 serializer.py 中将 create() 和 update() 方法重写为 POST json,但是层数太多 link。我对此一无所知。
下面是我的创建方法,但它只能POST MemberAccount 和UserData。
def create(self, validated_data):
memberaccount = MemberAccount.objects.create(account = validated_data['account'],
password = validated_data['password'] )
User_Datas = validated_data.pop('UserDatas')
for item in User_Datas:
userdata = UserData.objects.create(username = User_Datas.get('username'),
gender = User_Datas.get('gender'),
score = User_Datas.get('score'),
photo = User_Datas.get('photo'))
userdata.save()
return memberaccount
POST json 消息:
{"account":"try3","password":"8493","UserDatas":{"memberAccount_id":0,"username":"Amy","gender":false,"score":100,"photo":null,"TaskDatas":[],"FriendsDatas":[],"ChatroomDatas": []}}
这些是我看到的选项:
- 如果您不介意原子性(我不推荐此选项),您可以创建一组链式 POST 调用
- 拆分您的前端 UI/UX 这样您就可以隔离数据并使其易于处理。例如,每个面板都有不同的面板
- 在编辑时保存(在前端),因此您可以像以前一样同步小块数据
- 处理视图上的数据(后端)。您还需要处理原子性,但您可以依靠验证器。在这种情况下,您需要为它们中的每一个创建序列化程序实例
- 使用序列化器列表作为属性创建嵌套序列化器,但正如您所说,您可能需要处理多个层
只需将相关模型相应地保存如下:
def create(self, validated_data):
memberaccount = MemberAccount.objects.create(account = validated_data['account'],
password = validated_data['password'] )
memberaccount.save()
User_Datas = validated_data.pop('UserDatas')
userdata = UserData.objects.create(username = User_Datas.get('username'),
gender = User_Datas.get('gender'),
score = User_Datas.get('score'),
photo = User_Datas.get('photo'),)
userdata.memberAccount_id = memberaccount
userdata.save()
Task_Datas = User_Datas.get('TaskDatas')
for task in Task_Datas:
taskdata = TaskData(
task_name = task.get('task_name'),
task_is_group = task.get('task_is_group'),
task_time = task.get('task_time'),
task_score = task.get('task_score'),
task_member_list = task.get('task_member_list'),
task_bulletin = task.get('task_bulletin'),
)
taskdata.userData_id = userdata
taskdata.save()
return memberaccount
我是 Django 的新手,已经获取了数据。 部分json如下:
{
"pk": 4,
"account": "user4",
"password": "5340",
"UserDatas": {
"memberAccount_id": 4,
"username": "Dylan",
"gender": true,
"score": 100,
"photo": "photos/2016/05/16/avatar.png",
"TaskDatas": [
{
"userData_id": 4,
"task_name": "make a phone call",
"task_is_group": false,
"task_time": "2015/05/18",
"task_score": 2,
"task_member_list": "",
"task_bulletin": "phone number is 1234-5678"
}
],
"FriendsDatas": [],
"ChatroomDatas": []
}
},
这是我的 models.py
class MemberAccount(models.Model):
account = models.CharField(max_length=50)
password = models.CharField(max_length=30)
def __str__(self):
return "%s : %s" % (self.account, self.password)
class UserData(models.Model):
memberAccount_id = models.OneToOneField(
MemberAccount,
on_delete=models.CASCADE,
primary_key=True,
related_name='UserDatas',
blank=True
)
username = models.CharField(max_length=30, default="")
gender = models.BooleanField()
score = models.IntegerField()
photo = models.ImageField(upload_to ="photos/%Y/%m/%d/", null=True ,blank=True)
class Meta:
unique_together = ('memberAccount_id', 'username')
order_with_respect_to = 'memberAccount_id'
def __str__(self):
return "%s : %s" % (self.memberAccount_id, self.username)
class TaskData(models.Model):
userData_id = models.ForeignKey(UserData, related_name='TaskDatas', null=True)
task_name = models.CharField(max_length=100, default="")
task_is_group = models.BooleanField()
task_time= models.CharField(max_length=30)
task_score = models.IntegerField()
task_member_list = models.CharField(max_length=100, null=True ,blank=True)
task_bulletin = models.TextField(blank=True, default='')
class Meta:
unique_together = ('userData_id', 'task_name')
order_with_respect_to = 'userData_id'
def __str__(self):
return "%s : %s" % (self.userData_id, self.task_name)
class ChatroomData(models.Model):
userdata_cid = models.ForeignKey(UserData, related_name='ChatroomDatas', null=True, blank=True)
chatroom_member = models.CharField(max_length=30)
chatroom_contents = models.TextField(blank=True, default='')
def __str__(self):
# 在Python3中使用 def __str__(self)
return "%s : %s" % (self.userdata_cid, self.chatroom_member)
class FriendsData(models.Model):
usersData_id = models.ForeignKey(UserData, related_name='FriendsDatas', null=True)
friend_name = models.CharField(max_length=30)
friend_account = models.CharField(max_length=50)
class Meta:
unique_together = ('usersData_id', 'friend_name')
order_with_respect_to = 'usersData_id'
def __str__(self):
# 在Python3中使用 def __str__(self)
return "%s : %s" % (self.usersData_id, self.friend_name)
class SubtaskData(models.Model):
taskData_id = models.ForeignKey(TaskData, related_name='SubtaskDatas', null=True)
subtask_name = models.CharField(max_length=100)
subtask_deadline = models.CharField(max_length=30)
subtask_completion= models.IntegerField()
subtask_importance = models.IntegerField()
subtask_item = models.TextField(blank=True, default='')
class Meta:
unique_together = ('taskData_id', 'subtask_name')
order_with_respect_to = 'taskData_id'
def __str__(self):
# 在Python3中使用 def __str__(self)
return "%s : %s" % (self.taskData_id, self.subtask_name)
views.py
@api_view(['GET','POST'])
def jobterm_list(request, format=None):
if request.method=="GET":
MemberAccounts =list(MemberAccount.objects.all())
serializer = MemberAccountSerializer(MemberAccounts,many=True)
return Response(serializer.data)
elif request.method == 'POST':
#print (request.body)
serializer = MemberAccountSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
else:
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
@api_view(['GET', 'PUT', 'DELETE']) #
def jobterm_detial(request,pk, format=None):
try:
member_Account = MemberAccount.objects.get(pk=pk)
except MemberAccount.DoesNotExist:
return Response(status=status.HTTP_404_NOT_FOUND)
if request.method == "GET":
serializer = MemberAccountSerializer(member_Account)
return Response(serializer.data)
elif request.method == "PUT":
serializer = MemberAccountSerializer(member_Account,data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
else:
return Response(serializer.errors,status=status.HTTP_400_BAD_REQUEST)
elif request.method == "DELETE":
member_Account.delete()
return Response(status=status.HTTP_204_NO_CONTENT)
serializer.py
class ChatroomDataSerializer(serializers.ModelSerializer):
class Meta:
model = ChatroomData
fields = ("userdata_cid", "chatroom_member", "chatroom_contents")
class TaskDataSerializer(serializers.ModelSerializer):
class Meta:
model = TaskData
fields = ("userData_id", "task_name", "task_is_group",
"task_time", "task_score", "task_member_list",
"task_bulletin")
class FriendsDataSerializer(serializers.ModelSerializer):
class Meta:
model = FriendsData
fields = ("usersData_id","friend_name","friend_account")
class UserDataSerializer(serializers.ModelSerializer):
TaskDatas = TaskDataSerializer( many = True )
FriendsDatas = FriendsDataSerializer( many = True )
ChatroomDatas = ChatroomDataSerializer( many = True )
class Meta:
model = UserData
fields = ("memberAccount_id","username","gender","score",
"photo","TaskDatas","FriendsDatas","ChatroomDatas")
class MemberAccountSerializer(serializers.ModelSerializer):
UserDatas = UserDataSerializer( required = False )
class Meta:
model = MemberAccount
fields = ("pk","account","password","UserDatas")
class SubtaskDataSerializer(serializers.ModelSerializer):
class Meta:
model = SubtaskData
fields = ("taskData_id","subtask_name","subtask_deadline","subtask_completion",
"subtask_importance","subtask_item")
我尝试在 serializer.py 中将 create() 和 update() 方法重写为 POST json,但是层数太多 link。我对此一无所知。
下面是我的创建方法,但它只能POST MemberAccount 和UserData。
def create(self, validated_data):
memberaccount = MemberAccount.objects.create(account = validated_data['account'],
password = validated_data['password'] )
User_Datas = validated_data.pop('UserDatas')
for item in User_Datas:
userdata = UserData.objects.create(username = User_Datas.get('username'),
gender = User_Datas.get('gender'),
score = User_Datas.get('score'),
photo = User_Datas.get('photo'))
userdata.save()
return memberaccount
POST json 消息:
{"account":"try3","password":"8493","UserDatas":{"memberAccount_id":0,"username":"Amy","gender":false,"score":100,"photo":null,"TaskDatas":[],"FriendsDatas":[],"ChatroomDatas": []}}
这些是我看到的选项:
- 如果您不介意原子性(我不推荐此选项),您可以创建一组链式 POST 调用
- 拆分您的前端 UI/UX 这样您就可以隔离数据并使其易于处理。例如,每个面板都有不同的面板
- 在编辑时保存(在前端),因此您可以像以前一样同步小块数据
- 处理视图上的数据(后端)。您还需要处理原子性,但您可以依靠验证器。在这种情况下,您需要为它们中的每一个创建序列化程序实例
- 使用序列化器列表作为属性创建嵌套序列化器,但正如您所说,您可能需要处理多个层
只需将相关模型相应地保存如下:
def create(self, validated_data):
memberaccount = MemberAccount.objects.create(account = validated_data['account'],
password = validated_data['password'] )
memberaccount.save()
User_Datas = validated_data.pop('UserDatas')
userdata = UserData.objects.create(username = User_Datas.get('username'),
gender = User_Datas.get('gender'),
score = User_Datas.get('score'),
photo = User_Datas.get('photo'),)
userdata.memberAccount_id = memberaccount
userdata.save()
Task_Datas = User_Datas.get('TaskDatas')
for task in Task_Datas:
taskdata = TaskData(
task_name = task.get('task_name'),
task_is_group = task.get('task_is_group'),
task_time = task.get('task_time'),
task_score = task.get('task_score'),
task_member_list = task.get('task_member_list'),
task_bulletin = task.get('task_bulletin'),
)
taskdata.userData_id = userdata
taskdata.save()
return memberaccount