簡體   English   中英

Django REST API 查詢相關字段

[英]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可以是AverageTimeMaximumTemperature

然后, 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 個相關的RunRunParameter ,這將返回您所追求的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_idrun_parameter_id的重復條目,那么它會拋出錯誤。 為避免這種情況,請使用unique_together=['run', 'run_parameter']或者您可以在視圖中使用queryset.filter(**filter).first()而不是get_object_or_404 但是當創建重復條目時,第二個選項會產生錯誤的結果。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM