![](/img/trans.png)
[英]Django Rest Framework - Receive Primary Key in POST Response body
[英]Django Rest Framework receive primary key value in POST and return model object as nested serializer
我不完全確定我的問題的標題是我想要的那樣具體,但事實是這樣的:
我有一個HyperlinkedModelSerializer
,如下所示:
class ParentArrivalSerializer(serializers.HyperlinkedModelSerializer):
carpool = SchoolBuildingCarpoolSerializer()
class Meta:
model = ParentArrival
正如您所看到的, carpool
被定義為嵌套的序列化程序對象,我想要的是能夠以這種方式發出POST請求以創建ParentArrival
(數據為application / json):
{
...
"carpool": "http://localhost:8000/api/school-building-carpools/10/"
...
}
並以這種方式接收數據:
{
"carpool": {
"url": "http://localhost:8000/api/school-building-carpools/10/"
"name": "Name of the carpool",
...
}
}
基本上,我正在尋找一種處理嵌套序列化程序的方法,而不必在POST請求中將數據作為對象(但在這種情況下為id或url)發送,但接收對象嵌套在序列化響應中。
我對以前的解決方案感到滿意,但我決定重新審視,我認為我有另一種解決方案可以完全滿足您的需求。
基本上,您需要創建自己的自定義字段,並且只需覆蓋to_representation
方法:
class CarpoolField(serializers.PrimaryKeyRelatedField):
def to_representation(self, value):
pk = super(CarpoolField, self).to_representation(value)
try:
item = ParentArrival.objects.get(pk=pk)
serializer = CarpoolSerializer(item)
return serializer.data
except ParentArrival.DoesNotExist:
return None
def get_choices(self, cutoff=None):
queryset = self.get_queryset()
if queryset is None:
return {}
return OrderedDict([(item.id, str(item)) for item in queryset])
class ParentArrivalSerializer(serializers.HyperlinkedModelSerializer):
carpool = CarpoolField(queryset=Carpool.objects.all())
class Meta:
model = ParentArrival
這將允許您發布
{
"carpool": 10
}
得到:
{
"carpool": {
"url": "http://localhost:8000/api/school-building-carpools/10/"
"name": "Name of the carpool",
...
}
}
這很簡單。 如您所知, Django appends "_id" to the field name
ModelClass中Django appends "_id" to the field name
,您可以在SerializerClass中實現它,並且還可以實現原始Django appends "_id" to the field name
。 你所要做的就是這樣
class ParentArrivalSerializer(serializers.HyperlinkedModelSerializer):
# ...
carpool_id = serializers.IntegerField(write_only=True)
carpool = SchoolBuildingCarpoolSerializer(read_only=True)
# ...
class Meta:
fields = ('carpool_id', 'carpool', ...)
並在POST請求中使用carpool_id
。
一種方法是將“拼車”保持為DRF的默認值,然后為嵌套對象添加只讀字段。
像這樣的東西(我沒有時間測試代碼,所以請考慮這個偽代碼。如果你不能讓它工作,請告訴我,並將花更多的時間):
class ParentArrivalSerializer(serializers.HyperlinkedModelSerializer):
carpool_info = serializers.SerializerMethodField(read_only=True)
class Meta:
model = ParentArrival
fields = ('id', 'carpool', 'carpool_info',)
def get_carpool_info(self, obj):
carpool = obj.carpool
serializer = SchoolBuildingCarpoolSerializer(carpool)
return serializer.data
如果您的唯一嵌套對象是拼車,我還建議切換到常規ModelSerializer,因此拼車只顯示ID(10),然后嵌套對象可以顯示URL。
class ParentArrivalSerializer(serializers.ModelSerializer):
....
然后,如果一切正常,你將能夠發一個帖子
{
"carpool": 10
}
而你得到:
{
"carpool": 10
"carpool_info": {
"url": "http://localhost:8000/api/school-building-carpools/10/"
"name": "Name of the carpool",
...
}
}
我從來沒有找到另一個解決方案,所以這是我多次使用的技巧。
覆蓋to_representation
方法怎么樣?
class YourSerializer(serializers.ModelSerializer):
class Meta:
model = ModelClass
fields = ["id", "foreignkey"]
def to_representation(self, instance):
data = super(YourSerializer, self).to_representation(instance)
data['foreignkey'] = YourNestedSerializer(instance.foreignkey).data
return data
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.