[英]Django REST API query on related field
我有 3 個模型,Run、RunParameter、RunValue:
class Run(models.Model):
start_time = models.DateTimeField(db_index=True)
end_time = models.DateTimeField()
class RunParameter(models.Model):
parameter = models.ForeignKey(Parameter, on_delete=models.CASCADE)
class RunValue(models.Model):
run = models.ForeignKey(Run, on_delete=models.CASCADE)
run_parameter = models.ForeignKey(RunParameter, on_delete=models.CASCADE)
value = models.FloatField(default=0)
class Meta:
unique_together=(('run','run_parameter'),)
Run可以有一個RunValue ,它是一個浮點值,其值的名稱來自RunParameter (基本上是一個包含名稱的表),例如:
RunValue可以是AverageTime或MaximumTemperature
然后, Run可以具有RunValue = RunParameter:AverageTime值 X。
另一個Run實例可能具有RunValue = RunParameter:MaximumTemperature值 Y 等。
我創建了一個端點來查詢我的 API,但我只有RunParameter ID(因為您可以通過 select 直接繪制哪個參數),而不是RunValue ID。 我基本上顯示了所有RunParameter的列表和所有Run實例的列表,因為如果我顯示了RunValue的所有實例,那么該列表將太長且令人困惑,因為您不會看到“最高溫度”,而是會看到:
“運行 X 的最高溫度”
“運行 Y 的最高溫度”
“運行 Z 的最高溫度”等(重復 50 次以上)。
我的 API 視圖如下所示:
class RunValuesDetailAPIView(RetrieveAPIView):
queryset = RunValue.objects.all()
serializer_class = RunValuesDetailSerializer
permission_classes = [IsOwnerOrReadOnly]]
其序列化程序如下所示:
class RunValuesDetailSerializer(ModelSerializer):
run = SerializerMethodField()
class Meta:
model = RunValue
fields = [
'id',
'run',
'run_parameter',
'value'
]
def get_run(self, obj):
return str(obj.run)
還有 URL 以防萬一:
url(r'^run-values/(?P<pk>\d+)/$', RunValuesDetailAPIView.as_view(), name='values_list_detail'),
Since I'm new to REST API, so far I've only dealt with having the ID of the model API view I am querying directly, but never an ID of a related field. 我不確定在哪里修改我的查詢集以將其傳遞給 ID 以從相關字段中獲取適當的 model 實例。
在我進行 API 查詢時,我有Run instance ID 和RunParameter ID。 我需要查詢集是:
run_value = RunValue.objects.get(run=run_id, run_parameter_id=param_id)
到目前為止,我只需要做類似的事情:
run_value = RunValue.objects.get(id=value_id) # I don't have this ID
如果我理解正確,您正在嘗試獲取只有Run
id 和RunParameter
id 的RunValue
實例,即基於相關字段的查詢。
查詢集可以通過以下方式實現:
run_value = RunValue.objects.get(
run__id=run_id,
run_parameter__id=run_parameter_id
)
假設一個RunValue
實例只有 1 個相關的Run
和RunParameter
,這將返回您所追求的RunValue
實例。
如果這不是你的意思,請告訴我。
雙下划線允許您訪問查詢中的相關實例字段。
好吧,它非常簡單,您所要做的就是覆蓋get_object
方法,例如(從文檔中復制粘貼):
# view
from django.shortcuts import get_object_or_404
class RunValuesDetailAPIView(RetrieveAPIView):
queryset = RunValue.objects.all()
serializer_class = RunValuesDetailSerializer
permission_classes = [IsOwnerOrReadOnly]]
lookup_fields = ["run_id", "run_parameter_id"]
def get_object(self):
queryset = self.get_queryset() # Get the base queryset
queryset = self.filter_queryset(queryset) # Apply any filter backends
filter = {}
for field in self.lookup_fields:
if self.kwargs[field]: # Ignore empty fields.
filter[field] = self.kwargs[field]
obj = get_object_or_404(queryset, **filter) # Lookup the object
self.check_object_permissions(self.request, obj)
return obj
# url
url(r'^run-values/(?P<run_id>\d+)/(?P<run_parameter_id>\d+)/$', RunValuesDetailAPIView.as_view(), name='values_list_detail'),
但是你需要注意的一件大事是不要有相同的run_id
和run_parameter_id
的重復條目,那么它會拋出錯誤。 為避免這種情況,請使用unique_together=['run', 'run_parameter']
或者您可以在視圖中使用queryset.filter(**filter).first()
而不是get_object_or_404
。 但是當創建重復條目時,第二個選項會產生錯誤的結果。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.