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

#python #django #django-views #orm

Вопрос:

Как ученик фреймворка 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 get_next(request):

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

home.html

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

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

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

Ответ №1:

Когда вы публикуете URL-адрес get_next, вы должны отправить 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 и если вы не определили иное в Мета-файле своего класса, order_by не требуется. По умолчанию они упорядочены по PK.