嵌套关系序列化程序中的Django Rest Framework模型Id字段 [英] Django Rest Framework model Id field in nested relationship serializer

查看:208
本文介绍了嵌套关系序列化程序中的Django Rest Framework模型Id字段的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  class ServiceSerializer(serializers.ModelSerializer):我正在使用Django Rest框架,其中有两个序列化程序: 
id = serializers.ReadOnlyField()

class Meta:
model = ServiceType
fields =('id','serviceName','servicePrice')


class CompanyShortListSerializer(serializers.ModelSerializer):

services = ServiceSerializer(many = True)

class Meta:
model =公司
fields =('id','name','address','cost_per_patient','cost_per_month','renting_fee','services')
pre>

ServiceType模型如下所示:

  class ServiceType 
serviceName = EncryptedCharField(max_length = 100,blank = True,verbose_name =Typusługi)
servicePrice = EncryptedFloatField(null = True,blank = True,verbose_name =Cenausługi ,validators = [MinValueValidator(0.1),MaxValueValidator(999)])
company = models.ForeignKey(Company,related_name ='services')

我想通过更改相关服务来更新现有的实例(例如删除其中的一些)。为了实现这一点,我在这样做:

  def update(self,instance,validated_data):
# exisitng具有多个服务的公司
instance.name = validated_data ['name']
instance.address = validated_data ['address']
instance.cost_per_patient = validated_data ['cost_per_patient']
instance.renting_fee = validated_data ['renting_fee']
services_data = validated_data ['services']

service_data中的项目:
updatedService = ServiceType(
serviceName = item ['serviceName'],
servicePrice = item ['servicePrice'],
id = item ['id'],
company = instance)
updatedService.save()

返回实例

我所面临的问题是, code> service ['id'] 字段不提供 - 这意味着我得到一个 KeyError'id' - alt hough我明确地在 ServiceSerializer id 字段中添加。



编辑



这是一个示例性的请求(从Chrome获取) m发帖:

  {id:49,name:Test 1,
address :Testowa 1,
renting_fee:200,
cost_per_month:300,
cost_per_patient:null,
services:[
{ id:67,serviceName:Terapia,servicePrice:100},
{id:68,serviceName:Terapia par,servicePrice:150},
{id:69,serviceName:Terapia po angielsku,servicePrice:120}
]
}

我做错了什么,如何使用嵌套序列化程序获取对象的ID(基本上是ServiceSerializer)?



EDIT no.2



当我从串行器更新功能I得到以下内容:



print(self.data ['services'])给我:

  [
OrderedDict([('id',67),('serviceName',u'Terapia'),('servicePrice ',100.0)]),
OrderedDict([('id',68),('serviceName',u'Terapia par'),('servicePrice',150.0)]),
OrderedDict [('id',69),('serviceName',u'Terapia po angielsku'),('servicePrice',120.0)]),
OrderedDict([('id',70),('serviceName '',你'tperapia grupowa'),('servicePrice',140.0)])
]

但是, print(services_data)给出以下(基本相同但没有id):

  [
OrderedDict([(u'serviceName',u'Terapia')),(u'servicePrice',100.0)]),
OrderedDict([(u' serviceName',u'Terapia par'),(u 'servicePrice',150.0)]),
OrderedDict([(u'serviceName',u'Terapia po angielsku'),(u'servicePrice',120.0)])
]

ids 丢失...



编辑3号



根据 Django Rest Framework文档如果某个字段将在序列化器输出表示中应该是一个 HiddenField 。然而,这需要一个默认值值...我已经检查过,确实使用了这个HiddenField,默认值解决问题 - 该validated_data中的ID。问题是 id 不正确。是否有可能将此 id 设置为发送到序列化程序的对象的值?

解决方案

好吧 - 我想我找到答案,仔细阅读文档 :)



所以根据< a href =http://www.django-rest-framework.org/api-guide/fields/#modelfield =noreferrer>文档 id 字段可以这样设置为ModelField:

  id = serializers.ModelField(model_field = ServiceType()。 _meta.get_field('id'))

确实,在添加这行后, id 字段存在于validated_data :)


I'm usign Django Rest Framework where I have the following two serializers:

class ServiceSerializer(serializers.ModelSerializer):
    id = serializers.ReadOnlyField()

    class Meta:
        model = ServiceType
        fields = ('id', 'serviceName', 'servicePrice')


class CompanyShortListSerializer(serializers.ModelSerializer):

     services = ServiceSerializer(many=True)

     class Meta:
         model = Company
         fields = ( 'id','name','address','cost_per_patient','cost_per_month','renting_fee','services')

The ServiceType model looks like this:

class ServiceType(models.Model):
     serviceName = EncryptedCharField(max_length=100, blank=True, verbose_name = "Typ usługi")
     servicePrice = EncryptedFloatField(null=True, blank=True, verbose_name = "Cena usługi", validators = [MinValueValidator(0.1), MaxValueValidator(999)])
     company = models.ForeignKey(Company, related_name = 'services')

I would like to update the existing instances by changing the related services (e.g. deleting some of them). To achieve this I'm doing this:

def update(self, instance, validated_data):
    # Updates an exisitng Company with several services 
    instance.name = validated_data['name']
    instance.address = validated_data['address']
    instance.cost_per_patient = validated_data['cost_per_patient']
    instance.renting_fee = validated_data['renting_fee']
    services_data = validated_data['services']

    for item in services_data:
        updatedService = ServiceType(
            serviceName = item['serviceName'],
            servicePrice = item['servicePrice'],
            id=item['id'], 
            company=instance)
        updatedService.save()

    return instance

The problem that I'm facing is that the service['id'] field is not provided - which means I get a KeyError 'id' - although I added it explicitly in the ServiceSerializer id field.

EDIT

Here's an exemplary request (taken from Chrome) that I'm posting:

 { "id":49,"name":"Test 1",
   "address":"Testowa 1",
   "renting_fee":200,
   "cost_per_month":300,
   "cost_per_patient":null,
   "services":[
   {"id":67,"serviceName":"Terapia","servicePrice":100},
   {"id":68,"serviceName":"Terapia par","servicePrice":150},
   {"id":69,"serviceName":"Terapia po angielsku","servicePrice":120}
   ]
 } 

What am I doing wrong and how to get the ID of a an object(basically ServiceSerializer) using nested serializers?

EDIT no.2

When I print from the serializer update function I get the following:

print(self.data['services']) gives me:

[
 OrderedDict([('id', 67), ('serviceName', u'Terapia'), ('servicePrice', 100.0)]),
 OrderedDict([('id', 68), ('serviceName', u'Terapia par'), ('servicePrice', 150.0)]),
 OrderedDict([('id', 69), ('serviceName', u'Terapia po angielsku'), ('servicePrice', 120.0)]), 
 OrderedDict([('id', 70), ('serviceName', u'Terapia grupowa'), ('servicePrice', 140.0)])
]

However, print(services_data) gives the following (basically the same, but without the id):

[
OrderedDict([(u'serviceName', u'Terapia'), (u'servicePrice', 100.0)]),
OrderedDict([(u'serviceName', u'Terapia par'), (u'servicePrice', 150.0)]),
OrderedDict([(u'serviceName', u'Terapia po angielsku'), (u'servicePrice', 120.0)])
]

And the ids get lost ...

EDIT no.3

According to the Django Rest Framework docs If certain field will be shall be in the serializer output representation it should be a HiddenField. This however requires a default value ... I have checked that and indeed using this HiddenField with a default value 'solves' the problem - the ID is there in validated_data. The problem is that the id is not correct. Is there a possibility to set this id to the value of the object sent to the serializer?

解决方案

Ok - I think I found the answer after ... carefully reading the docs :)

So according to the docs the id field could be set to a ModelField like this:

id = serializers.ModelField(model_field=ServiceType()._meta.get_field('id'))

Indeed, after adding this line the id field is present in validated_data :)

这篇关于嵌套关系序列化程序中的Django Rest Framework模型Id字段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆