Пагинированная конечная точка REST API для записей django-simple-history, используя Django REST Framework

Я использую django-simple-history для отслеживания изменений модели.

Получить все записи истории для класса модели или экземпляра модели достаточно просто:

poll = Poll.objects.create(question="what's up?", pub_date=datetime.now())
poll.history.all()
# and
Choice.history.all()

Но что я хочу сделать, так это иметь конечные точки, такие как /history/model и /history/model/1, которые возвращают постраничные записи истории либо для класса, либо для экземпляра класса.

Теперь я уже настроил Django REST Framework (DRF) с пагинацией, и все мои представления пагинированы, примерно так:

class MyModelViewSet(viewsets.ModelViewSet):
    serializer_class = MyModelSerializer
    permission_classes = [permissions.IsAuthenticated]
    queryset = MyModel.objects.all()

class MyModelSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = MyModel
        fields = ["name"]

class MyModel(models.Model):
    name = models.CharField(max_length=100, unique=True)

Все работает нормально.

Как я могу постранично расположить django-simple-history записи?

Могу ли я создать простой сериализатор истории? Потому что не существует простой модели истории, которую я мог бы использовать (я думаю).

Я собираюсь использовать модель Poll для этого примера и создал приложение под названием polls.

class Poll(models.Model):
   question = models.CharField(max_length=200)
   pub_date = models.DateTimeField('date published', auto_now_add=True)
   history = HistoricalRecords()

После миграции создается новая таблица под названием 'polls_historicalpoll'. Вы можете использовать команду inspectdb для создания модели для этого или просто создать ее вручную, посмотрев на поле в базе данных. Например.

class HistoricalPoll(models.Model):
    id = models.BigIntegerField()
    question = models.CharField(max_length=200)
    pub_date = models.DateTimeField()
    history_id = models.AutoField(primary_key=True)
    history_date = models.DateTimeField()
    history_change_reason = models.CharField(max_length=100, blank=True, null=True)
    history_type = models.CharField(max_length=1)
    history_user = models.ForeignKey(get_user_model(), models.DO_NOTHING, blank=True, null=True)

    class Meta:
        managed = False
        db_table = 'polls_historicalpoll'

Теперь вы можете создать сериализатор для этой модели:

#serializers.py
from rest_framework import serializers
from .models import HistoricalPoll

class HistoricalPollSerializer(serializers.ModelSerializer):

    class Meta:
        model = HistoricalPoll
        fields = '__all__'

Теперь, когда у вас есть сериализатор, вы можете создать ModelViewset. Чтобы упростить задачу, я переписал метод get_queryset для фильтрации по id опроса, но вы также можете использовать djangofilterbackend, см. https://www.django-rest-framework.org/api-guide/filtering/#djangofilterbackend

#views.py
from rest_framework import viewsets, permissions
from polls.models import HistoricalPoll
from polls.serializers import HistoricalPollSerializer


class HistoricalPollViewSet(viewsets.ModelViewSet):
    serializer_class = HistoricalPollSerializer
    permission_classes = [permissions.IsAuthenticated]
    queryset = HistoricalPoll.objects.all()

    def get_queryset(self):
        poll_id = self.request.GET.get('poll_id')
        return HistoricalPoll.objects.filter(id=poll_id)

В зависимости от ваших ссылок вы можете получить доступ ко всей истории опросов, как это: http://127.0.0.1:8000/api/v1/polls/historical_polls

Или вы можете отфильтровать по id опроса следующим образом: http://127.0.0.1:8000/api/v1/polls/historical_polls?poll_id=3

Это отлично сработало для меня. Дайте мне знать, если это поможет вам.

django-simple-history обеспечивают способ взаимодействия с моделью истории. Ниже приведен пример того, как можно создать серализатор.

class PollHistorySerializer(serializers.ModelSerializer):
    class Meta:
        model = Poll.history.model
        fields = '__all__'

Обратите внимание на Poll.history.model, используемый для доступа к истории модели. Затем вы можете использовать этот серайлайзер для постраничного просмотра истории модели.

class PollHistoryPaginatedView(generics.ListAPIView):
    pagination_class = YourPaginationClass
    serializer_class = PollHistorySerializer
    
    def get_queryset(self):
        return Poll.history.all()
Вернуться на верх