#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.