Преобразование django RawQuerySet в Queryset

У меня есть 2 модели Django, ModelA с ArrayField, которые используются для хранения большого списка значений первичного ключа (возможно, список 50k+)

class ModelA(models.Model):
    pk_values = ArrayField(models.IntegerField())

class CustomManager(manager.Manager):

    def get_for_index(self, index_id):
        qs = self.get_queryset()
        obj = ModelA.objects.get(pk=index_id)
        return qs.filter(id__in=obj.pk_values)

class ModelB(models.Model):
    # [...] some fields

    objects = CustomManager()

Это работает:

qs = ModelB.objects.get_for_index(index_id=1)

Однако это было бы очень медленно, если "pk_values" - это большой список.

Итак, я попытался выполнить необработанные SQL-запросы:

class CustomManager(manager.Manager):
    def get_for_index(self, index_id):
        qs = self.get_queryset()
        sql = "SELECT * FROM myapp_model_b JOIN myapp_model_a ON myapp_model_b.id = ANY(myapp_model_a.pk_values) WHERE myapp_model_a.id = '%s'" % index_id
        return qs.raw(sql)

Но это возвращает экземпляр django.db.models.query.RawQuerySet.

Но после этого я не могу делать такие вещи, как queryset.values().

Как я могу преобразовать это в обычный набор запросов Django?

Есть ли лучший способ сделать это?

Документы:


person mishbah    schedule 16.01.2018    source источник
comment
Я мог что-то упустить, но вы можете использовать ManyToManyField?   -  person internet_user    schedule 16.01.2018
comment
Это существующие модели ... поэтому я не могу их изменить.   -  person mishbah    schedule 16.01.2018


Ответы (2)



Обновление: у меня что-то работает, используя .extra()

class CustomManager(manager.Manager):
    def get_for_index(self, index_id):
        qs = self.get_queryset()
        sql = "myapp_model_b.id IN (SELECT UNNEST(myapp_model_a.pk_values) FROM myapp_model_a WHERE myapp_model_a.id='%s')" % index_id
        return qs.extra(where=[sql])

Документы: https://docs.djangoproject.com/en/2.0/ref/models/querysets/#django.db.models.query.QuerySet.extra

person mishbah    schedule 17.01.2018