Непрерывный циклический просмотр всех объектов в таблице с помощью django

Изучая фреймворк django, я столкнулся с проблемой перебора всех первичных ключей таблицы, начиная с первого, и в конце последовательности начинать все сначала. Поле id является автоинкрементным последовательным полем в postgres. Очень базовая разбивка проекта выглядит следующим образом:

models.py

...
class Event(models.Model):
    id = models.BigAutoField(primary_key=True)
    event_name = models.BigIntegerField(blank=True, null=False)
    timestamp = models.DateTimeField(blank=True, null=True)
    viewed = models.BooleanField(default=False)

views.py

def home(request, id=None):
    from .models import Event

    first_obj = Event.objects.order_by('id').first()
    my_json = serialize('json', first_obj, fields=('event_name', 'timestamp'))

    return render(request, 'home.html', {'items': my_json})

def confirm(request):

     #set viewed=True on current object
    .save()
     return redirect('home') #move to next object

home.html

...
<form method="POST" action="{% url 'confirm' %}">
<button>confirm</button>
</form>
...

Идея заключается в том, чтобы отправить объект my_json в html-шаблон. Пользователь нажимает кнопку, которая должна пометить текущий объект как просмотренный (устанавливает viewed из False в True), затем должен быть извлечен следующий объект (по инкрементальному первичному ключу), и так далее. Если он достиг последнего объекта, то следующим должен быть извлечен первый объект (pk=1), и цикл продолжается. Я хотел бы избежать ajax-запросов и думаю, что второй url будет наиболее эффективным способом сделать это, но не уверен, как действовать дальше.

Должен ли текущий pk id отправляться туда и обратно между запросами и увеличиваться каждый раз? Есть ли встроенный метод для этой концепции в django? Каким должен быть эффективный метод перебора всех первичных ключей? Любой совет о том, как лучше структурировать эту концепцию, будет высоко оценен!

Когда вы пишете в get_next url, вы должны послать PK текущего события. Тогда event = get_object_or_404(Event, pk=request.post.get("pk") выдаст вам текущее событие. event.viewed = True event.save().

В домашнем представлении вы должны сделать:

event = Event.objects.filter(viewed=False).order_by("pk")
if not event.exists():
    Event.objects.all().update(viewed=False) #only in Django 2.2+ I think
    event = Event.objects.order_by("pk").first()
else:
    event = event.first()
return ...

Я думаю, это даст вам цикл, когда все просмотрены, мы устанавливаем их обратно на непросмотренные и начинаем с первого снова.

Также, если вы используете целочисленные PK, и если вы не определили иное в Meta вашего класса, order_by не нужен. По умолчанию они упорядочиваются по PK.

Вернуться на верх