Предварительная выборка косвенно связанных элементов с помощью Django ORM - PullRequest
0 голосов
/ 19 апреля 2019

Я пытаюсь оптимизировать запросы для моей системы модерирования, сборка с Django и DRF.В настоящее время я застрял с поиском дубликатов: в настоящее время у меня есть что-то вроде

class AdminSerializer(ModelSerializer):
    duplicates = SerializerMethodField()

    def get_duplicates(self, item):
        if item.allowed:
            qs = []
        else:
            qs = Item.objects.filter(
                    allowed=True, 
                    related_stuff__language=item.related_stuff.language
                ).annotate(
                    similarity=TrigramSimilarity('name', item.name)
                ).filter(similarity__gt=0.2).order_by('-similarity')[:10]
    return AdminMinimalSerializer(qs, many=True).data

, которое прекрасно работает, но выполняет по крайней мере один дополнительный запрос для каждого элемента для отображения.Кроме того, если есть дубликаты, я сделаю дополнительные запросы, чтобы заполнить AdminMinimalSerializer, который содержит поля и связанные объекты дублированного элемента.Вероятно, я могу уменьшить накладные расходы, используя prefetch_related внутри сериализатора, но это не мешает мне делать несколько запросов на элемент (при условии, что у меня есть только один связанный элемент для предварительной выборки в AdminMinimalSerializer, у меня все равно будет ~2N + 1 запросов: 1 для элементов, N для дубликатов, N для связанных элементов дубликатов).

Я уже посмотрел Subquery, но не могу получить объект,только идентификатор, и этого не достаточно в моем случае.Я пытался использовать его как в объекте Prefetch, так и в .annotate.

Я также пытался использовать что-то вроде Item.filter(allowed=False).prefetch(Prefetch("related_stuff__language__related_stuff_set__items", queryset=Items.filter..., to_attr="duplicates")), но свойство duplicates добавлено в "related_stuff__language__related_stuff_set", поэтому я могу 'я действительно не могу его использовать ...

Я приветствую любую идею;)

...