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