2016-04-07 21 views
12

Tôi đang usign Django Nghỉ ngơi Khung nơi tôi có hai serializers sau:mô hình Django Nghỉ ngơi Khung Id trường trong mối quan hệ lồng nhau serializer

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') 

Mô hình Loại Dịch vụ trông như thế này:

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') 

tôi muốn cập nhật các phiên bản hiện tại bằng cách thay đổi các dịch vụ liên quan (ví dụ: xóa một số dịch vụ). Để đạt được điều này tôi đang làm điều này:

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 

Vấn đề mà tôi đang phải đối mặt là lĩnh vực service['id'] không được cung cấp - có nghĩa là tôi có được một KeyError 'id' - mặc dù tôi đã thêm nó một cách rõ ràng trong lĩnh vực ServiceSerializerid.

EDIT

Dưới đây là một yêu cầu gương mẫu (lấy từ Chrome) mà tôi gửi bài:

{ "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} 
    ] 
} 

Tôi đang làm gì sai và làm thế nào để có được ID của một đối tượng (về cơ bản ServiceSerializer) bằng cách sử dụng serializers lồng nhau?

EDIT no.2

Khi tôi in từ các chức năng cập nhật serializer tôi nhận được như sau:

print(self.data['services']) mang lại cho tôi:

[ 
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)]) 
] 

Tuy nhiên, print(services_data) đưa ra sau (cơ bản giống nhau, nhưng không có 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)]) 
] 
.210

ids bị lạc ...

EDIT số 3

Theo Django Rest Framework docs Nếu một số lĩnh vực sẽ phải được lập thành đại diện đầu ra serializer nó phải là một HiddenField. Tuy nhiên điều này đòi hỏi một giá trị default ... Tôi đã kiểm tra và thực sự sử dụng HiddenField này với một giá trị mặc định 'giải quyết' vấn đề - ID có trong validated_data. Vấn đề là id không chính xác. Có khả năng để thiết lập này id đến giá trị của đối tượng được gửi đến serializer?

Trả lời

15

Ok - Tôi nghĩ rằng tôi đã tìm thấy câu trả lời sau ...cẩn thận đọc the docs :)

Vì vậy, theo the docs lĩnh vực id có thể được thiết lập để một ModelField như thế này:

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

Thật vậy, sau khi thêm dòng này lĩnh vực id hiện diện trong validated_data :)

+4

Cảm ơn bạn đã lưu ngày của tôi :-) – bre

+0

Bạn vừa lưu một cuộc sống khác !. Tài liệu DRF là một mê cung. Thông tin quan trọng được ẩn sâu trong tài liệu. Cảm ơn – danidee

2

Bạn đã đặt id làm ReadOnlyField. Đó là lý do tại sao id không xuất hiện trong dữ liệu được xác thực. Chỉ cần xóa dòng này:

id = serializers.ReadOnlyField() 
+0

Thật không may, sau khi loại bỏ này, tôi vẫn nhận được 'KeyError 'id'' từ serializer ... :( – user1544500

+0

Làm thế nào để JSON trông mà bạn gửi Bạn có thể thêm video này vào bạn Câu hỏi? – ilse2005

+0

Tôi đã thêm Yêu cầu mẫu từ Chrome. Tôi hy vọng điều đó đủ? – user1544500

4

Câu trả lời được chấp nhận hoạt động nhưng phức tạp không cần thiết. Bạn chỉ có thể thay đổi trường ID thành không đọc được. Ví dụ. một cái gì đó như thế này sẽ làm:?

id = serializers.IntegerField(required=False) 
+0

Thật vậy, nó cũng hoạt động. –

Các vấn đề liên quan