Опрос Django на производном поле - PullRequest
1 голос
/ 25 апреля 2019

Использование Django 1.8

У меня есть неуправляемая модель, которая указывает на представление в БД, и я пытаюсь вернуть набор запросов на основе производного поля.

Вот базовый пример структуры модели:

class Book(models.Model):
    book_id = models.IntegerField()
    publisher = models.CharField(max_length=20, null=True) # Can join to Publisher.publisher_name
    sku = models.CharField(max_length=15, null=True) # Can join to Sku.sku

    class Meta:
        managed = False
        db_table = 'vw_book'


class Sku(models.Model):
    sku = models.CharField(max_length=15)
    publisher = models.ForeignKey('myapp.Publisher')


class Publisher(models.Model):
    publisher_name = models.CharField(max_lenth=20)
    region = models.ForeignKey('myapp.Region')


class Region(models.Model):
    region_name = models.CharField(max_length=20)

Я ищу способ вернуть набор запросов Book, основанный на регионе, полученный от издателя в качестве предпочтительного поля, а затем от sku. Эти поля в Книге могут ссылаться на поля разных регионов, поскольку данные не являются объектами и получены из нескольких источников. Я могу добавить метод в модель Book для получения региона, но попытка получить набор запросов из этого слишком медленная.

class Book(models.Model):
    publisher = models.CharField(max_length=20, null=True)
    sku = models.CharField(max_length=15, null=True)

    class Meta:
        managed = False
        db_table = 'vw_book'

    def get_region(self):
        if not self.publisher:
            if not self.sku:
                return ''
            try:
               sku = Sku.objects.get(sku=self.sku)
               return sku.publisher.region.region_name
            except Sku.DoesNotExist:
               return ''
         try:
             publisher = Publisher.objects.get(publisher_name=self.publisher)
             return publisher.region.region_name
         except Publisher.DoesNotExist:
             return ''


region_dict = {}
for book in Book.objects.all():
    region_dict.setdefault(book.get_region(), []).append(book.book_id)

Book.objects.filter(book_id__in=region_dict.get('UK', []))

Я не могу добавить дополнительное поле в модель Book. Есть ли более эффективный способ сделать это?

1 Ответ

1 голос
/ 25 апреля 2019

Я бы отфильтровал Skus, а затем отфильтровал книги на основе полученного Skus

skus = Sku.objects.filter(publisher__region__region_name=region).values_list('sku', flat=True)
Book.objects.filter(sku__in=skus)

Вы можете сделать то же самое с издателями, если потребуется, и выполнить запрос Or.

 .filter(Q(publisher__in=publishers) |Q(sku__in=skus))
...