2016-07-19 42 views
7

我有很多鏈接模型到它:如何通過串行器創建模型實例,而無需從嵌套的串行器創建模型?

class Travel(BaseAbstractModel): 

    tags = models.ManyToManyField(
     Tag, 
     related_name='travels', 
     ) 
    owner = models.ForeignKey(
     'users.TravelUser', 
     related_name='travel_owner' 
     ) 
    payment = models.ForeignKey(
     Payment, 
     related_name='travels', 
     ) 
    country = models.ForeignKey(
     Country, 
     related_name='travels, 
     ) 
    ........ 

許多車型都只有兩個唯一的名稱和圖像領域。 我對每一個模型的創建串並把它們在TravelSerializer

class TravelBaseSerializer(DynamicFieldsModelSerializer): 

    owner = UserSerializer(required=False) 
    tags = TagSerializer(many=True) 
    payment = PaymentSerializer() 
    country = CountrySerializer() 

基於文檔我重寫create()update
問題是,當我發送JSON數據時,Django從嵌套序列化器創建每個模型。但我只想創建Travel實例。另外我想接收並響應序列化對象不僅pk字段。

UPDATE
我解決了這個問題,把代碼放在答案裏。現在,我可以接收和響應串行器數據而無需創建對象。 但我認爲DRF提供了更優雅的方法,然後我就做到了。這是我與DRF的第一個項目,也許我錯過了一些東西,並有一個更簡單的解決方案。

回答

2

我決定重寫to_internal_value()把它放在定製serailizer並從它繼承所有嵌套串行:

class NestedRelatedSerializer(serializers.ModelSerializer): 

    def to_internal_value(self, data): 
     try: 
      pk = data['pk'] 
     except (TypeError, KeyError): 
     # parse pk from request JSON 
      raise serializers.ValidationError({'_error': 'object must provide pk!'}) 
     return pk 

從中獲取所有pk和保存createupdated方法:

def update(self, instance, validated_data): 
     # If don't get instance from db, m2m field won't update immediately 
     # I don't understand why 
     instance = Travel.objects.get(pk=instance.pk) 
     instance.payment_id = validated_data.get('payment', instance.payment_id) 
     instance.country_id = validated_data.get('country', instance.country_id) 
     # update m2m links 
     instance.tags.clear() 
     instance.tags.add(*validated_data.get('tags')) 
     instance.save() 
     return instance 
1

我米不完全確定我明白你想做什麼,但可以設置read_only_fieldsMeta類是你需要什麼?

class TravelBaseSerializer(DynamicFieldsModelSerializer): 

    owner = UserSerializer(required=False) 
    tags = TagSerializer(many=True) 
    payment = PaymentSerializer() 
    country = CountrySerializer() 

    class Meta: 
     read_only_fields = ('tags',) 

看到文檔this section

+0

謝謝,但我在第一件事情中嘗試過。 ''read_only_fields'問題,這些字段不會傳遞給'validated_data' –

+0

好,所以我想你想要的是:你想要當你的序列化器用於閱讀puproses時,它序列化所有相關的字段,並且當用於寫它嘗試驗證相關字段但不保存它們的puproses。如果我錯了,請糾正我。 – AntoineWDG

+0

是的,但我需要'validated_data'中的這些數據,因爲我需要填充創建的'Travel'模型中的所有鏈接字段。我解決它,就像你在我的答案中看到的一樣。但是我開始這個賞金,因爲我希望找到一些最佳實踐,以達到這樣的目的。現在我想,DRF只是不允許使用嵌套序列化器來達到這樣的目的,默認情況下 –