繁体   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