Django Serialiser получает записи о братьях и сестрах
В Django DRF я пытаюсь понять, могу ли я вернуть объекты, являющиеся братьями и сестрами. Например, у меня есть запись B, могу ли я вернуть записи A и B?
Затем я могу использовать их для циклической записи в блоге, например, со ссылками на предыдущую и следующую статью.
На данный момент я получаю текущий объект, а затем снова обращаюсь к базе данных в поисках записи с тем же родителем. Я думаю, что может быть есть более эффективный способ.
Ваше решение на самом деле нормально, потому что все наборы запросов в Django являются ленивыми объектами и оцениваются только при доступе. Это означает, что ваш "сложный" запрос будет выбирать только один элемент из базы данных за одно выполнение.
Если вам нужно улучшение, вы можете выбрать только одно поле parent_id
из queryset. Т.е.:
parent_id = self.queryset.filter(
pk=service_id).values_list('parent_id', flat=True).first()
# this will produce SQL query:
# SELECT your_app_service.parent_id from your_app_service
# WHERE your_app_service.id = service_id
queryset = (
self.queryset.filter(
parent_id=parent_id, id__lt=service_id
)
.exclude(pk=service_id)
.order_by("-id")
.first()
)
# and this one will give you the following query:
# SELECT <all_fields from model> FROM <table>
# WHERE (parent_id = parent_id AND id < service_id
# AND NOT(id = service_id)) ORDER BY id DESC
И тогда .first()
будет просто выбирать первый элемент из этого курсора (без выборки всех элементов из DB).
Вдруг в голову пришел другой ответ.
Если вы используете ModelViewSet из DRF - у вас есть эта функциональность, встроенная в paginator.
settings.py
REST_FRAMEWORK = {
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination',
'PAGE_SIZE': 100
}
Тогда каждый запрос к одному объекту будет иметь дополнительные теги для объектов previous
и next
, если вы также зададите limit
и offset
в качестве URL-параметров. Например:
curl --location --request GET 'http://10.100.102.10:8004/garage/customers/?limit=1&offset=1'
Возврат:
{
"count": 13,
"next": "http://10.100.102.10:8004/garage/customers/?limit=1&offset=2",
"previous": "http://10.100.102.10:8004/garage/customers/?limit=1",
"results": [
{
"id": 9,
"passport_number": 8,
"first_name": "John",
"last_name": "Smith",
"email": null,
"age": 7,
"city": null
}
]
}
Так что вы можете использовать ссылки then из ответа для перехода назад и вперед по элементам