Как переключаться между подробными представлениями для пользовательских наборов данных в django (python)?
В таблице (назовем это элементами) Я открываю подробные представления для элемента. В подробном представлении мне нужны кнопки "следующий" и "предыдущий". Кнопка должна открывать подробное представление следующих элементов. Я не могу просто просмотреть все наборы данных, потому что пользователь не может получить доступ к наборам данных других пользователей.
Я думал об использовании двусвязного списка, где данные в узлах содержат идентификатор текущего набора данных, а в качестве указателей - идентификатор следующего и предыдущего элементов. Когда пользователь достигает конца, он автоматически переходит к началу и наоборот. Но я не хочу загружать этот список каждый раз, когда пользователь открывает следующий подробный просмотр.
Существует ли простой в использовании способ переключения между подробными представлениями без простого увеличения идентификатора?
Вы можете ограничить запрос одним объектом, используя нотацию разбиения списка, но для достижения этой цели вам потребуется настроить метод get_object.
# For next item
class NextItemDetailView(LoginRequiredMixin, DetailView):
# using the same template as ItemDetailView
template_name = "item.html"
def get_object(self, queryset=None):
pk = self.kwargs.get(self.pk_url_kwarg)
try:
obj = self.request.item_set\
.filter(id__gt=pk)\
.order_by('id')[:1].get()
except Item.DoesNotExists:
raise Http404('No more item')
return obj
Затем в urls.py
urlpatterns = [
# ...
path("item/<int:pk>/next/", views.NextItemDetailView.as_view(), name="next-item")
]
И в шаблоне
<a class="button" href="{% url 'next-item' item.id %}">next</a>
Получение предыдущего элемента аналогично. Просто измените условие фильтрации на lt
вместо gt
и порядок на '-id'
для убывания.
Я думаю, вы слишком все усложняете! Вам не нужен связанный список или сложные структуры данных. ORM в Django может эффективно справиться с этим с помощью простых запросов к базе данных.
Вы можете сделать что-то вроде этого
class ItemDetailView(LoginRequiredMixin, DetailView):
model = Item
template_name = "item.html"
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
current_item = self.get_object()
# Get next item (first item with ID > current, ordered by ID)
next_item = Item.objects.filter(
user=self.request.user, # Security: only user's items
id__gt=current_item.id
).order_by('id').first()
# Get previous item (first item with ID < current, ordered descending)
prev_item = Item.objects.filter(
user=self.request.user,
id__lt=current_item.id
).order_by('-id').first()
# Handle circular navigation (wrap around)
if not next_item:
next_item = Item.objects.filter(user=self.request.user).order_by('id').first()
if not prev_item:
prev_item = Item.objects.filter(user=self.request.user).order_by('-id').first()
context['next_item_id'] = next_item.id if next_item else None
context['prev_item_id'] = prev_item.id if prev_item else None
return context
И в вашем шаблоне:
{% if prev_item_id %}
<a class='button' href='{% url "item" prev_item_id %}'>Previous</a>
{% endif %}
{% if next_item_id %}
<a class='button' href='{% url "item" next_item_id %}'>Next</a>
{% endif %}