我在django中有两个数据库表:"设备"表存储实际设备和" DeviceTest"用于存储每个设备的测试检查的表(对一个设备进行多次测试)。
class Device(models.Model):
created_at = models.DateTimeField(auto_now_add=True)
name = models.CharField(max_length=20)
serial_number = models.CharField(max_length=20)
def __unicode__(self):
return self.name + " - " + self.serial_number
class DeviceTest(models.Model):
device = models.ForeignKey(Device)
created_at = models.DateTimeField(auto_now_add=True)
TEST_OK = '+'
TEST_ERROR = '-'
TEST_RESULT_CHOICES = (
(TEST_OK, 'Test Success'),
(TEST_ERROR, 'Test Error'),
)
status = models.CharField(max_length=1, choices=TEST_RESULT_CHOICES, default=TEST_ERROR)
comment = models.TextField(blank=True, default="")
tester = models.CharField(max_length=255)
action = models.CharField(max_length=255)
def __unicode__(self):
return self.device.name + " - " + \
self.device.serial_number + " - " + \
unicode(self.created_at) + " - " + \
u"Result (" + self.status + ")"
我已经制作了包含所有设备表格的HTML页面:
name | serial number | created_at | last_test_time | last_test_status | hyperlink to test table page
现在我想给用户所有的排序可能性。我通过GET参数为#34; name","序列号"和" created_at"领域。而现在,我仍然坚持使用" last_test_time"和" last_test_status"字段。
使用一些标准的Django函数可以解决这个问题吗?像Device.objects.all().filter(???).order_by(???)
答案 0 :(得分:1)
您可以annotate使用最新created_at
时间的查询集。
from django.db.models import Max
queryset = Device.objects.annotate(last_test_time=Max('devicetest__created_at'))
您可以为每个对象访问last_test_time
。
for obj in queryset
print(obj.last_test_time)
您可以按此字段订购查询集
queryset = queryset.order_by('last_test_time')
但是,这只是部分答案,因为它无法帮助您获得该测试的状态。
您可以单独查找每个设备。
for device in queryset:
device.latest_status = device.device_test.latest('created_at').status
如果设备数量很少,这是可以的,但这意味着每个设备有一个查询,这与设备数量的增加并不理想。
您可以使用prefetch_related
在一个查询中获取所有相关的设备测试。 (下面的代码未经测试,我的语法可能略有错误。)
queryset = queryset.prefetch_related(Prefetch('devicetest', DeviceTest.objects.order_by('-created_at'))
然后,您可以通过第一次相关设备测试获取状态。
for obj in queryset:
print obj.devicetest.all()[0].status
请注意,这是低效的,因为您已加载所有相关项目,而不仅仅是最新项目。