Как переключаться между подробными представлениями для пользовательских наборов данных в 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 %}
Вернуться на верх