Django通过查找相关字段值进行注解

e5nqia27  于 2022-12-20  发布在  Go
关注(0)|答案(1)|浏览(151)

我正在Django中开发一个包裹分拣系统。我需要查找一组"barcodes"中的"sort code"

class Order(models.Model):
    Zip = CharField(max_length=128, null=True, blank=True)

class Barcode(models.Model):
    barcode = CharField(max_length=50, unique=True)
    Order = ForeignKey(Order, on_delete=models.SET_NULL)

class SortCode(models.Model):
    name = CharField(max_length=50, unique=True)

class SortZip(models.Model):
    zipcode = CharField(max_length=5, unique=True)
    sortcode = ForeignKey('SortCode', null=True, default=None, blank=True, on_delete=models.PROTECT)


sortzip = SortZip.objects.filter(zipcode=OuterRef('Order__Zip'))
barcodes = Barcode.objects.annotate(sortcode_value=Subquery(sortzip.values('sortcode__name')))

但是,SortZip.zipcode只存储5位数的邮政编码,而Order.Zip有时包含zip+4,所以我只需要从Order.Zip的前5位数查找SortZip

sortzip = SortZip.objects.filter(zipcode=OuterRef('Order__Zip')[:5])
barcodes = Barcode.objects.annotate(sortcode_value=Subquery(sortzip.values('sortcode__name')))

这将导致以下错误:

TypeError: 'OuterRef' object is not subscriptable

我尝试将以下属性添加到Order模型并使用该属性:

class Order(models.Model):
    Zip = CharField(max_length=128, null=True, blank=True)

    @property
    def Zip5(self):
       return self.Zip[:5]
...

sortzip = SortZip.objects.filter(zipcode=OuterRef('Order__Zip5'))
barcodes = Barcode.objects.annotate(sortcode_value=Subquery(sortzip.values('sortcode__name')))

但是,这会产生不同的错误:

django.core.exceptions.FieldError: Unsupported lookup 'Zip5' for BigAutoField or join on the field not permitted.
wj8zmpe1

wj8zmpe11#

截断字符串的正确方法是使用Left函数。

from django.db.models.functions import Left

sortzip = SortZip.objects.filter(zipcode=OuterRef(Left('order__zip', 5)))

相关问题