热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Django迁移问题:TypeError:实例之间不支持'<'

本文讨论了将Django项目从Python2.7/Django1.11迁移到Python3.7/Django2.1时遇到的一个TypeError问题,该问题涉及实例之间不支持'<'操作符的错误。文章介绍了问题的背景和原因,并提供了相关的代码示例。

我正在尝试将我的Django项目从Python 2.7 / Django 1.11迁移到Python 3.7 / Django 2.1.

我发现了一个问题,我想了解它的原因.

我的项目中有3个模型:

class DeviceModel(models.Model):
name = models.CharField(max_length=255)
pirsh = models.CharField(max_length=255)
def __str__(self):
return self.name + " - " + self.pirsh
class Device(models.Model):
created_at = models.DateTimeField(auto_now_add=True)
device_model = models.ForeignKey(DeviceModel, on_delete=models.CASCADE)
serial_number = models.CharField(max_length=255)
def __str__(self):
return self.device_model.name + " - " + self.device_model.pirsh + " - " + self.serial_number
class DeviceTest(models.Model):
device = models.ForeignKey(Device, on_delete=models.CASCADE)
created_at = models.DateTimeField()
TEST_OK = '+'
TEST_ERROR = '-'
TEST_PENDING = '?'
TEST_RESULT_CHOICES = (
(TEST_OK, 'Success'),
(TEST_ERROR, 'Fail'),
(TEST_PENDING, 'Not checked'),
)
status = models.CharField(max_length=1, choices=TEST_RESULT_CHOICES, default=TEST_PENDING)
comment = models.TextField(blank=True, default="")
tester = models.CharField(max_length=255)
action = models.CharField(max_length=255)
def save(self, *args, **kwargs):
''' On save, update timestamps '''
if not self.created_at:
self.created_at = timezone.now()
return super(DeviceTest, self).save(*args, **kwargs)
def __str__(self):
return self.device_id.device_model.name + " - " + self.device_id.device_model.pirsh + " - " + self.device_id.serial_number + " - " + str(self.created_at) + " - " + "Result (" + self.status + ")"

这是我按最新测试状态排序设备对象的代码(‘dev_filter’,’field’和’order’参数是从GET请求解析的):

if (dev_filter!="") and (dev_filter!="-1"):
device_list = Device.objects.all().filter(device_model = dev_filter)
else:
device_list = Device.objects.all()
dev_status_list = []
for dev in device_list:
try:
dev_status_list.append(DeviceTest.objects.filter(device_id=dev.pk).latest('created_at').status)
except:
dev_status_list.append("Not checked")
device_list = [device_list for (dev_status_list, device_list) in sorted(zip(dev_status_list, device_list))]
if (order == '-'):
device_list.reverse()

这段代码在Python 2.7 / Django 1.11中运行良好,但在Python 3.7 / Django 2.1中却没有

Django标记为错误排序(zip(dev_status_list,device_list))函数:

TypeError: '<' not supported between instances of 'Device' and 'Device'

我看到这个问题的两个解决方案:要么使用

device_list = [device_list for (dev_status_list, device_list) in sorted(zip(dev_status_list, device_list), key=lambda x: (x[0],x[1].__str__()))]

或者将__lt__方法添加到设备模型:

def __lt__(self, other):
return self.__str__()

我的问题是 – 改变了什么?由于Python升级或Django升级,是否会发生此错误?什么是用于Device对象的Python 2.7 / Django 1.11框架中的默认排序方法?我纠正它是字符串表示吗?我最喜欢哪种解决方案?

解决方法:

Python 3引入了新的ordering comparison:

The ordering comparison operators (<, <=, >=, >) raise a TypeError exception when the operands don’t have a meaningful natural ordering.

一个简单的例子,它在Python2中打印True并在Python3中引发TypeError

class A:
pass
print(A()


推荐阅读
author-avatar
顆顆顆顆幸福_483
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有