Добавление динамических полей в сериализатор в django-rest-framework - PullRequest
0 голосов
/ 09 января 2019

У меня есть модель

    class Event(models.Model):
        random_fields...

    class Registrations(models.Model):
        user = models.ForeignKey(User...)
        event = models.ForeignKey(Event...)
        ts = models.DateTimeField(...)

Теперь я хочу получить список всех событий вместе с тем, зарегистрирован ли пользователь, который сделал request, в этом событии или нет (поле is_registered в ModelSerializer Event возможно).

В идеале это должно происходить в одном запросе, а не слишком много database queries.

Какой эффективный способ сделать это?

1 Ответ

0 голосов
/ 09 января 2019

Я думаю, вы можете использовать prefetch related для сокращения запросов к БД. При извлечении регистраций из события вы можете использовать prefetch_related для извлечения всех регистраций одновременно (поэтому запрос нескольких дБ не требуется).

Итак, для начала вы можете определить модель следующим образом:

class Registrations(models.Model):
    user = models.ForeignKey(User...)
    event = models.ForeignKey(Event, related_name="registrations",..)

Затем вы можете определить EventSerializer следующим образом:

class EventSerializer(serializer.ModelSerializer):
    registrations = RegistrationSerializer(many=True, read_only=True)  # <-- getting all registraions via RegistrationSerializer
    is_invited = serializer.SerializerMethodField()

    class Meta:
       model = Event
       fields = "__all__"

    def get_is_invited(self, obj):
        return obj.registrations.filter(user=self.context.get("request").user).exists()  # does not make any DB query

SerializerMethodField используется здесь для получения, если пользователь приглашен или нет.

Теперь в представлении при вызове набора запросов Event используйте prefetch_related.

# A minimal example

class SomeView(APIView):
    def get(self, request, **kwargs):
        qset = Event.objects.prefetch_related('registrations').all()
        serializer = EventSerializer(qset, many=True)
        return Response(serializer.data)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...