Django:TypeError:“<"实例之间不支持(模型对象) [英] Django: TypeError: '<' not supported between instances (model objects)

查看:119
本文介绍了Django:TypeError:“<"实例之间不支持(模型对象)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm trying to migrate my Django project from Python 2.7/Django 1.11 to Python 3.7/Django 2.1.

我找到了一个问题,我想了解其原因.

I've found one issue and I want to understand its cause.

我的项目中有3个模型:

I have 3 models in my project:

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 + ")"

这是我的代码,用于按最新测试状态对Device个对象进行排序(从GET请求中解析"dev_filter","field"和"order"参数):

And this is my code to sort Device objects by latest test status ('dev_filter', 'field' and 'order' parameters are parsed from GET request):

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中却没有

This code worked fine in Python 2.7/Django 1.11 but it doesn't in Python 3.7/Django 2.1

Django将其标记为错误sorted(zip(dev_status_list, device_list))函数:

Django marks as error sorted(zip(dev_status_list, device_list)) function:

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

我看到了解决该问题的两种方法:要么使用

I see two solutions to this problem: either use

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__方法添加到Device模型:

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

我的问题是-发生了什么变化?是否由于Python升级或Django升级而发生此错误? Python 2.7/Django 1.11框架中Device对象的默认排序方法是什么?我是否正确,它是字符串表示形式?而我的哪种解决方案是首选?

My question is - what is changed? Does this error happen because of Python upgrade or Django upgrade? What was default sorting method in Python 2.7/Django 1.11 framework for Device objects? Am I correct that it was string representation? And which of my solutions is preferred?

推荐答案

Python 3引入了新的排序比较:

Python 3 introduces new ordering comparison:

当操作数没有有意义的自然排序时,排序比较运算符(<,< =,> =,>)会引发 TypeError 异常.

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

A simple example which prints True in Python2 and raises a TypeError in Python3

class A:
    pass

print(A() < A())

这篇关于Django:TypeError:“&lt;"实例之间不支持(模型对象)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆