Пагинированная конечная точка 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()