Django аннотирует путем поиска значения связанного поля

Я работаю над системой сортировки пакетов в Django. Мне нужно найти "код сортировки" набора "штрих-кодов" Этот код работает:

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, поэтому мне нужно искать SortZip только по первым 5 цифрам Order.Zip:

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.

Правильным способом усечения строки является использование функции Left.

from django.db.models.functions import Left

sortzip = SortZip.objects.filter(zipcode=OuterRef(Left('order__zip', 5)))
Вернуться на верх