2017-10-12 91 views
2

所以我剛開始使用Django Rest Framework,我的一個序列化器有一個MultipleChoiceField,其中的選擇只是其他模型的所有實例。Django Rest Framework具有動態選項的MultipleChoiceField

這裏是有問題的串行:

class ObjectTypeSerializer(serializers.ModelSerializer): 

    def get_field_choices(): 
     return sorted([ 
      (p.id, p.name) for p in Parameter.objects.all() 
     ]) 

    object_fields = serializers.MultipleChoiceField(
     choices=get_field_choices() 
    ) 

    instance_fields = serializers.MultipleChoiceField(
     choices=get_field_choices() 
    ) 

    labels = serializers.SlugRelatedField(
     queryset=Label.objects.all(), 
     many=True, allow_null=True, slug_field='name' 
    ) 

    class Meta: 
     model = ObjectType 
     fields = ('id', 'name', 'object_fields', 
        'instance_fields', 'labels') 

然而,當我添加一個新的參數對象,不更新的選擇。在常規的Django的形式,我解決了這個簡單的使用

forms.ChoiceField(choices=[(p.id, p.name) for p in Parameter.objects.all()]) 

,並在無需重新啓動服務器添加一個新的參數,將更新的選擇。我如何用Django Rest Framework序列化器完成同樣的事情?

任何幫助表示讚賞。謝謝!

回答

1

當你的選擇是模型時,最直接的方法是使用RelatedField的一些衍生物。鑑於您使用的是p.idPrimaryKeyRelatedField是否適合您? (如果沒有請更新您的問題)

如果默認行爲(使用了顯示數值模型__unicode__)是你的願望沒有什麼,你總是可以繼承它,並重新定義display_value方法:

class CustomPKRelatedField(serializers.PrimaryKeyRelatedField): 
    """A PrimaryKeyRelatedField derivative that uses named field for the display value.""" 

    def __init__(self, **kwargs): 
     self.display_field = kwargs.pop("display_field", "name") 
     super(CustomPKRelatedField, self).__init__(**kwargs) 

    def display_value(self, instance): 
     # Use a specific field rather than model stringification 
     return getattr(instance, self.display_field) 

... 
class ObjectTypeSerializer(serializers.ModelSerializer): 
    ... 
    object_fields = CustomPKRelatedField(queryset=Parameter.objects.all(), many=True) 
    instance_fields = CustomPKRelatedField(queryset=Parameter.objects.all(), many=True) 
    ... 
... 

如果你所需要的只是如此BrowsableAPIRenderer將呈現一個漂亮的外觀<select>,我相信這就是你需要做的。


ChoiceFieldMultipleChoiceField被設計成一個靜態數據集工作。他們甚至預處理__init__以允許分組。這就是爲什麼新項目不會出現在那裏的原因 - 這些字段本質上是永久性地「緩存」結果(直到服務器重新啓動)。

如果由於某種原因,你真的需要它ChoiceField - 衍生物,您可以設置post_savepost_delete葛聽衆和更新域choices(和grouped_choices如果你不是一個非常前沿的版本,其中一個已包含PR to allow choices to be set dynamically)屬性。有關詳細信息,請檢查ChoiceFieldsource code。雖然這將是一個骯髒的黑客。 ;)

相關問題