Я пытаюсь вернуть запрос через Django ORM, который приводит к этому объекту:
[
...,
{
"id": 1,
"product_id": 1,
"created_at": "2020-03-03T03:34:59.275941Z",
"updated_at": "2020-03-03T03:34:59.291653Z",
"latest_comment": {
"comment": "Leaving a comment",
"author": {
"id": 1,
"name": "John Lennon",
"profile": {
"avatar": null
}
},
"updated_at": "2020-03-03T03:34:59.329229Z"
}
}
]
У меня есть следующие модели:
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
avatar = models.ImageField(upload_to="avatar", blank=True)
created_at = models.DateTimeField(default=timezone.now)
updated_at = AutoDateTimeField(default=timezone.now)
class Product(models.Model):
name = models.CharField(max_length=100)
created_at = models.DateTimeField(default=timezone.now)
updated_at = AutoDateTimeField(default=timezone.now)
class Note(models.Model):
product = models.ForeignKey(Product, related_name="notes", on_delete=models.CASCADE)
created_at = models.DateTimeField(default=timezone.now)
updated_at = AutoDateTimeField(default=timezone.now)
class Comment(models.Model):
note = models.ForeignKey(Note, related_name="comments", on_delete=models.CASCADE)
comment = models.TextField()
author = models.ForeignKey(User, on_delete=models.CASCADE)
created_at = models.DateTimeField(default=timezone.now)
updated_at = AutoDateTimeField(default=timezone.now)
class Meta:
get_latest_by = "updated_at"
У меня есть Я смог достичь структуры, описанной выше, с помощью следующего кода, но он привел к проблеме N + 1.
product = Product.objects.get(id=1)
notes = []
for note in product.notes.all():
try:
note.latest_comment = note.comments.latest()
except ObjectDoesNotExist:
note.latest_comment = None
notes.append(note)
Я играл с prefetch_related
, а также с аннотациями с функцией Max
без особого успеха. Я также был в состоянии написать необработанный запрос, который может воспроизвести это, используя некоторые Postgres и функцию json_build_object
. Причина, по которой я пытаюсь заставить ORM работать, заключается в том, что я хотел бы использовать CursorPagination
, а использование .raw()
или RawSql()
не совместимо с CursorPagination
.