Как передать модель django-simple-history в Graphene-Django?
Я создал экземпляр simple_history.models.HistoricalRecords в моей модели Notification
models.py
class Notification(models.Model):
title = models.CharField(max_length=500)
content = RichTextField()
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
history = HistoricalRecords()
class Attachment(models.Model):
title = models.CharField(max_length=500)
attachement = models.FileField(upload_to = user_directory_path)
notifiaction = models.ForeignKey(Notification, on_delete=models.SET_NULL, null= True)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
schema.py
class AttachmentNode(DjangoObjectType):
class Meta:
model = Attachment
filter_fields = ['title']
interfaces = (relay.Node, )
class NotificationNode(DjangoObjectType):
class Meta:
model = Notification
filter_fields = {
'id': ['exact'],
'title': ['exact', 'icontains', 'istartswith'],
}
interfaces = (relay.Node, )
class Query(graphene.ObjectType):
notifications = relay.Node.Field(NotificationNode)
all_notifications = DjangoFilterConnectionField(NotificationNode)
Это работает нормально, но я хочу, чтобы все записи также были в конечной точке graphql для HistoricalRecords(). Как я могу это сделать?
Я предполагаю, что вам нужна история каждого уведомления внутри него, возможно, чтобы показать ее где-то в вашем приложении.
Получение списка изменений из списка ревизий
Похоже, что есть проблема, которую вам придется решить в первую очередь - django-simple-history хранит ревизии объектов, а не различия. Вам придется придумать, как преобразовать это
[
<HistoricalNotification: Notification object as of 2010-10-25 18:04:13.814128>,
<HistoricalNotification: Notification object as of 2010-10-25 18:03:29.855689>,
]
к чему-то подобному, сравнивая соседние ревизии и находя различия:
[
"Created by Jack Pear 10 minutes ago",
"title changed by Jack Pear 8 minutes ago",
]
В действительности вам, вероятно, нужны dicts вместо stings, так что это легче обрабатывать на frontend.
Для этого существует инструмент , включенный в django-simple-history. Вот некоторый псевдокод того, как вы можете это сделать:
class Notification(models.Model):
title = models.CharField(max_length=500)
content = RichTextField()
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
history = HistoricalRecords()
def get_changelist(self):
record = self.history.first()
while record.next_record:
delta = record.diff_against(record.next_record)
for change in delta.changes:
yield {
"field": change.field,
"old": change.old,
"new": change.new,
"changed_by": record.next_record.history_user,
"changed_at": record.next_record.history_date,
}
record = record.next_record
Добавление списка изменений в graphql
Нам придется объявить отдельный ObjectType для объектов списка изменений:
class ChangeListItemNode(graphene.ObjectType):
field = graphene.ID()
old = graphene.ID()
new = graphene.ID()
changed_by = graphene.Field(UserNode)
changed_at = graphene.DateTime()
После этого мы объявляем пользовательское поле с резольвером на NotificationNode
:
class NotificationNode(DjangoObjectType):
changelist = graphene.List(ChangeListItemNode)
class Meta:
model = Notification
filter_fields = {
'id': ['exact'],
'title': ['exact', 'icontains', 'istartswith'],
}
interfaces = (relay.Node, )
@staticmethod
def resolve_changelist(notification, info, **kwargs):
return notification.get_changelist()
Помните, что это не тестировалось, это просто псевдокод и определенно содержит ошибки. Однако это должно послужить отправной точкой.