Непрерывный циклический просмотр всех объектов в таблице с помощью 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.