Django rest framework Django Rest框架关系序列化
我试图用外键获取以下模型的序列化数据,但在输出中,我只获取ID,而不是与hyperlink关联的模型字段 我曾尝试使用概要文件序列化程序中的注释行获取技能模型的所有字段,但没有成功 models.pyDjango rest framework Django Rest框架关系序列化,django-rest-framework,Django Rest Framework,我试图用外键获取以下模型的序列化数据,但在输出中,我只获取ID,而不是与hyperlink关联的模型字段 我曾尝试使用概要文件序列化程序中的注释行获取技能模型的所有字段,但没有成功 models.py class Profile(models.Model): user = models.OneToOneField( settings.AUTH_USER_MODEL, on_delete=models.CASCADE) first_name = models.Cha
class Profile(models.Model):
user = models.OneToOneField(
settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
first_name = models.CharField(max_length=20, null=True)
last_name = models.CharField(max_length=20, null=True)
def __str__(self):
return 'Profile for user {}'.format(self.user.username)
class Skill(models.Model):
skill = models.CharField(max_length=20, null=True)
level = models.CharField(max_length=20, null=True)
user = models.ForeignKey(Profile, null=True,
on_delete=models.PROTECT, related_name='skills')
def __str__(self):
return '%s: %s: %s' % (self.user, self.skill, self.level)
序列化程序.py
class SkillSerializer(serializers.ModelSerializer):
class Meta:
model = Skill
fields = ('user', 'skill', 'level')
class ProfileSerializer(serializers.ModelSerializer):
class Meta:
# skills = SkillSerializer(many=True, read_only=True) # serializes child model's data inside this model's data
# skills = serializers.HyperlinkedRelatedField(many=True, read_only=True, view_name='skill-detail')
# skills = serializers.StringRelatedField(many=True)
# skills = serializers.HyperlinkedIdentityField( view_name = "skill-list", lookup_field = "user")
url = HyperlinkedIdentityField( view_name="profile-detail", lookup_field = "id")
# user = serializers.ReadOnlyField(source='user.username')
# pdb.set_trace()
model = Profile
fields = ['id', 'user', 'url', 'skills']
views.py
class ProfileList(generics.ListCreateAPIView):
queryset = Profile.objects.all()
serializer_class = ProfileSerializer
class ProfileDetail(generics.RetrieveUpdateDestroyAPIView):
queryset = Profile.objects.all()
serializer_class = ProfileSerializer
class SkillList(generics.ListCreateAPIView):
queryset = Skill.objects.all()
serializer_class = SkillSerializer
class SkillDetail(generics.RetrieveUpdateDestroyAPIView):
queryset = Skill.objects.all()
serializer_class = SkillSerializer
url.py
path('profiles/', views.ProfileList.as_view(), name='profile-list'),
path('profiles/<int:pk>/', views.ProfileDetail.as_view(), name='profile-detail'),
path('skills/', views.SkillList.as_view(), name='profile-list'),
path('skills/<int:pk>/', views.SkillDetail.as_view(), name='skill-list'),
预期产出:
[ "id": 6,
"user": 4,
"url": "http://127.0.0.1:8000/authenticator/profiles/6/",
"skills": [
{
"user": 6,
"skill": "ABC",
"level": "Beginner"
},
{
"user": 6,
"skill": "DEF",
"level": "Intermediate"
},
]
]
这通常适用于serializer.py中的以下内容:
class ProfileSerializer(serializers.ModelSerializer):
skills = SkillSerializer(many=True, read_only=True) # serializes child model's data inside this model's data
url = HyperlinkedIdentityField( view_name="profile-detail", lookup_field = "id")
class Meta:
model = Profile
fields = ['id', 'user', 'url', 'skills']
因此,基本上取消对ProfileSerializer被告知使用SkillsSerializer序列化技能的行的注释,这样整个技能对象将包含在结果中,而不是其ID中。您可以使用嵌套序列化器的概念来解决此问题。
创建两个序列化程序
ProfileReadSerializer
和ProfileWriteSerializer
序列化程序.py
class SkillSerializer(serializers.ModelSerializer):
类元:
模型=技能
字段=(‘用户’、‘技能’、‘级别’)
类ProfileReadSerializer(serializers.ModelSerializer):
skills=SkillSerializer(many=True,read_only=True)
url=HyperlinkedEntityField(查看\u name=“配置文件详细信息”,查找\u field=“id”)
类元:
模型=外形
字段=('id','user','url','skills')
类ProfileWriteSerializer(serializers.ModelSerializer):
skills=SkillSerializer(many=True)
类元:
模型=外形
字段=('id','user','url','skills')
在视图中,您可以简单地使用ModelViewSet
简化操作,并使用get\u serializer\u class
views.py
从rest\u framework.viewset导入模型视图集
类ProfileVewSet(ModelViewSet):
queryset=Profile.objects.all()
def get_序列化程序_类(自身):
如果self.request.method==“POST”或self.request.method==“PUT”或self.request.method==“PATCH”:
返回配置文件WriteSerializer
其他:
返回ProfileReadSerializer
最后,如果您使用的是ModelViewSet
,则需要更改url.py
url.py
从rest\u framework.router导入默认路由器
路由器=默认路由器()
router.register('profile',views.ProfileViewSet,base_name='profile')
URL模式=[
路径(“”,包括(router.url))
]
我想这会解决你的问题。请看一看。我试过,同样的,实际上所有的注释行都是单独的,一行接一行,没有一行起作用。。。我猜我遗漏了一些基本点..嗯。在再次查看代码之后:这不是因为要序列化的字段应该在序列化程序类上声明,而不是在序列化程序的内部元类上声明吗?更新了我的答案。感谢您在上面的代码中进行了一些拼写更正,我能够获得预期的输出。但是在技能部分下的配置文件api页面中,我无法添加任何内容,因为输入框中显示“列表当前在HTML中不受支持”,您能帮我解决这个问题吗。。。因此,我也可以在浏览器中使用相同的url发布…您是否可以建议一些文档,让我能够清楚地了解Django Rest框架中的关系序列化。。。。。我试着看了一遍,但是示例代码是一个lil混淆。我已经编辑了上面的解决方案,您可以在这里查看当前HTML不支持的列表。我确实关注文章,另一个有用的链接是,如果我的答案正确,请检查。
class ProfileSerializer(serializers.ModelSerializer):
skills = SkillSerializer(many=True, read_only=True) # serializes child model's data inside this model's data
url = HyperlinkedIdentityField( view_name="profile-detail", lookup_field = "id")
class Meta:
model = Profile
fields = ['id', 'user', 'url', 'skills']