Django: Как фильтровать наборы запросов на основе глубоких вложенных отношений - PullRequest
0 голосов
/ 02 октября 2018

Отказ от ответственности: Английский не мой родной язык.Мне сложно сформулировать этот вопрос, поэтому он может быть дубликатом.Может быть, вы можете предложить лучший заголовок?

Я пытаюсь сделать эффективный набор запросов для вложенных отношений.Мне нужно, чтобы отношения охватывали несколько отношений «многие ко многим».

Позвольте мне дать вам модели и набор запросов, который я придумал, потому что я действительно не могу найти слова для описания моей проблемы, ноЯ могу выразить это легко в коде.Заметьте, что для краткости я пропустил поля.

from django.conf import settings


class UserWaiterProfile(models.Model):
    user = models.OneToOneField(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
    )


class Restaurant(models.Model):
    name = models.CharField()

    @cached_property
    def employees(self):
        return UserWaiterProfile.objects.filter(
            employment__restaurant=self, employment__status=1
        )


class Table(models.Model):
    number = models.PositiveSmallIntegerField()
    restaurants = models.ManyToManyField(Restaurant)


class Employment(models.Model):
    restaurant = models.ForeignKey(Restaurant)
    employee = models.ForeignKey(UserWaiterProfile)

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

# ... other imports
from fcm_django.models import FCMDevice
from django.contrib.auth import get_user_model


class SomeView(generics.GenericAPIView):
    def some_serializer_method(self, serializer):
        employments = Employment.objects.filter(restaurant__in=qr_code.table.restaurants.all())
        employees = UserWaiterProfile.objects.filter(employment__in=employments)
        user_queryset = get_user_model().objects.filter(userwaiterprofile__in=employees)
        fcm_devices = FCMDevice.objects.filter(
            user__in=user_queryset,
            active=True,
            name__icontains=SERVER_VALUES_FCM_WAITER_DEVICE_PREFIX
        )
        if fcm_devices.exists():
            fcm_devices.send_message(content_available=True, data={
                "data": serializer.data
            })

Как вы видите, мне нужно отправить сообщение на устройства, принадлежащие сотрудникам, которые работают в ресторанах для данной таблицы.Итак, мой вопрос: есть ли у Django возможность сделать этот запрос лучше?(В JavaScript я мог бы просто вкладывать фильтры и делать из них один слой.)

...