Django (DRF) - фильтрация родителя в рекурсивном поле на основе дочерних свойств - PullRequest
1 голос
/ 27 мая 2019

У меня есть рекурсивная модель.

class Organization(models.Model):
    business_name = models.CharField(max_length=100, unique=True)

    # recursive relationship
    organization = models.ForeignKey('self', on_delete=models.CASCADE, null=True, blank=True, related_name='organizations')

У меня есть другая модель, которая является дочерней по отношению к этой рекурсивной модели, и она может быть дочерней в любой точке дерева.

class Store(models.Model):
    registration_no = models.CharField(max_length=8, default=increment_registration_no, unique=True)
    organization = models.OneToOneField(Organization, on_delete=models.PROTECT, related_name='store', null=True)

В пользовательском интерфейсе для этого приложения список магазинов указан в рекурсивной таблице с заголовками организации выше.У нас есть сериализатор, специально разработанный для этого списка.Когда пользователь просматривает этот список, он может фильтровать по Organization и Store свойствам.

class StoreSerializer(serializers.ModelSerializer):
    registration_no = serializers.CharField(read_only=True)

    class Meta:
        model = Store
        fields = ('id', 'registration_no')

class StoreFilterSerializer(serializers.ModelSerializer):
    registration_no = serializers.CharField(read_only=True)

    def to_representation(self, value):
        # Turn single object into a query so that we can use django filters
        queryset = Store.objects.filter(pk=value.id)
        registration_no = self.context['request'].query_params.get('registration_no', None)

        if registration_no is not None:
            queryset = queryset.filter(registration_no__icontains=registration_no)

        if queryset:
            # Represent object with serializer defined above
            return StoreSerializer(queryset[0]).data
        else:
            return {}

    class Meta:
        model = Store


class OrganizationsSerializer(serializers.ModelSerializer):
    store = StoreFilterSerializer(read_only=True)
    organizations = RecursiveField(many=True)

    class Meta:
        model = Organization
        fields = ('id', 'business_name', 'organization', 'organizations', 'store')

Как вы можете видеть выше, если мы передадим registration_no, тогда магазины могут быть отфильтрованыиз.Однако предположим, что пользователь вводит строку, которая не соответствует ни одному хранилищу.Тогда никакие магазины не будут возвращены, но группа организаций будет возвращена.В пользовательском интерфейсе это приводит к тому, что таблица становится пустой, потому что нет строк магазина, но в меню разбивки на страницы есть каждая страница, потому что организации не фильтруются.

Таким образом, вопрос заключается в ,как мне отфильтровать организации по тому, будет ли у них хранилище где-нибудь внизу рекурсивного дерева ПОСЛЕ применения фильтров хранилища (registration_no)?

1 Ответ

0 голосов
/ 13 июня 2019

Решение, которое я выбрал, заключалось в том, чтобы отфильтровать нужные мне магазины и получить организации, а не отфильтровать организации по свойствам магазина.

Фильтр магазинов
различные способы сделать это

Получить всех родителей магазинов

all_orgs = []
for store in store_queryset:
  all_orgs.push(store.get_all_parents())

Получить все организации queryset = Organizations.objects.filter (organization__in = all_orgs) Затем верните орг

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...