我有3个模型,运行, sensor_parameter 和数据。其中有其他ForeignKey关系,但运行对 sensor_parameter 或数据没有直接的ForeignKey。
运行有 start_time 和 end_time ,并与分区相关。
class Run(models.Model):
start_time = models.DateTimeField(db_index=True)
end_time = models.DateTimeField(db_index=True)
chamber = models.ForeignKey(Chamber, on_delete=models.CASCADE)
室与传感器有关系,而传感器有 sensor_parameter (s)
class SensorParameter(models.Model):
sensor = models.ForeignKey(Sensor)
parameter = models.ForeignKey(Parameter)
数据点终于"属于"到 sensor_parameter :
class Data(models.Model):
time = models.DateTimeField(db_index=True)
sensor_parameter = models.ForeignKey(SensorParameter, on_delete=models.CASCADE)
parameter_value = models.FloatField()
我需要过滤属于运行的 sensor_parameter (s)列表,但我们之间唯一的链接是时间值。由于数据有时间戳,运行有 start_time 和 end_time ,我以为我可以过滤列表 data.sensor_parameter 在时间段范围内。
我不确定如何构建该查询集过滤器。
我已导入日期时间,并且可以访问django_filter。
这是我目前在views.py
中的内容import datetime
import django_filters
def get(self, request):
# Get a list of run objects, that are passed through the request
run_ids = request.GET.getlist('id')
runs = Run.objects.filter(pk__in=run_ids)
# Get a list of all chambers that own those runs
chamber = Chamber.objects.filter(run__in=runs).distinct()
# Get a list of all sensors that belong to those chambers
sensor = Sensor.objects.filter(chamber=chamber)
# Looking around, I saw these two DateTimeFilter expressions from django_filters
time__gte = django_filters.DateTimeFilter(name="time", lookup_expr='gte')
time__lte = django_filters.DateTimeFilter(name="time", lookup_expr='lte')
# Here I would have to determine which run.start_time is lower
# And which run.end_time is higher, to get a valid time range
# This part is not finished yet
time_start = run.start_time
time_end = run.end_time
# This is the filter I'm having trouble implementing
sensor_parameters = SensorParameter.objects.filter(sensor=sensor, data__time__gte=time_start, data__time__lte=time_end)
return render(request, self.template_name, {'run': run, 'sensor_parameters': sensor_parameters})
基本上,我想如果我从我的运行中提取 start_time 和 end_time (它可能不止一次运行,我必须确定哪个 start_time 较低且 end_time 更大),然后我可以使用时间范围对 data.time 过滤 sensor_parameter 。
我不知道如何从这里开始。
另外,如果有任何不同,我们会使用PostgreSQL。
如果您发现任何明显的错误或语法错误,请随时纠正和批评,我仍然是Django和Python的新手,但我喜欢它的每一分钟。
答案 0 :(得分:0)
我设法自己做,虽然我不确定我做这件事的方式是不是最好的方法。我将上面的代码保持不变,以证明问题出在哪里,并提供一个与我实现的解决方案相比较的点。
日期范围的想法是正确的,因为 data.time 是我唯一链接到 run.start_time - run.end_time 。
所以我通过将所有 run.start_time 和 run.end_time 添加到几个列表来确定 range_period ,然后我调用<这些列表上的strong> min()和 max()方法提取所需的句点,然后进入列表,这是(包含的) __范围过滤器需要输入。
以下是views.py,其中包含明确的注释:
class ChartRunsView(generic.DetailView):
model = Run
template_name = 'chart_runs.html'
def get(self, request):
# Get a list of run objects, that are passed through the request
run_ids = request.GET.getlist('id')
runs = Run.objects.filter(pk__in=run_ids)
# Get a list of all chambers that own those runs
chamber = Chamber.objects.filter(run__in=runs).distinct()
# Get a list of all sensors that belong to those chambers
sensor = Sensor.objects.filter(chamber=chamber)
# Initialize run_start and run_end lists
run_start_list = []
run_end_list = []
# Append start_time(s) and end_time(s) for all runs
for run in runs:
run_start_list.append(run.start_time)
run_end_list.append(run.end_time)
# Determine the earliest and latest time stamps for all the extracted run times
# Using Python's min() and max() list methods
runs_start = min(run_start_list)
runs_end = max(run_end_list)
# Build a new list with the earliest run_start and latest run_end
range_period = [runs_start, runs_end]
# Build query that will filter all SensorParameter objects against sensor, and data
# Using the __range filter method, which takes a list as input.
# This will return all SensorParameter objects in that time range, which could potentially
# be thousands. Applying the .distinct() filter method on the resulting queryset gives us
# only unique results
sensor_parameters = SensorParameter.objects.filter(sensor__in=sensor, data__time__range=range_period).distinct()
return render(request, self.template_name, {'runs': runs,
'sensor_parameters': sensor_parameters})