#python #django #list #stopiteration
#python #django #Список #остановка
Вопрос:
Я хотел бы получить вашу помощь в соответствии с моей проблемой: StopIteration
.
Principe:
У меня есть функция, которая получает в качестве аргументов список идентификаторов и определенный идентификатор. Этот список идентификаторов соответствует массиву с нумерацией страниц.
Эта функция вызывается, когда я создаю новый объект в этом массиве. Как только мой объект создан, я перенаправляюсь на нужную страницу в моем массиве.
Моя функция:
def get_pagination(my_list_of_objects, pk):
# if object doesn't exist, add id to list of objects
if pk not in my_list_of_objects:
my_list_of_objects.append(pk)
# Get the list of objects code splitted by PAGE_LIMIT sorted by code (default)
my_list_of_objects_code = MyModel.objects.values_list('code', flat=True).filter(id__in=my_list_of_objects)
pagination = [my_list_of_objects_code[x:x settings.PAGE_LIMIT] for x in range(0, len(my_list_of_objects_code), settings.PAGE_LIMIT)]
# Get first and last page number
first_page = 1
last_page = len(pagination)
# Get sublist index (e.g page number for specific id)
page_number = (next(index for index, value in enumerate(pagination) if pk in value)) 1
return pagination, first_page, last_page, page_number
Таким образом :
my_list_of_objects: идентификатор списка объектов
my_list_of_objects_code: список объектов, отсортированных по коду
разбивка на страницы: разделите список на подсписки с n элементами внутри. n соответствует нумерации страниц, установленной в настройках.
first_page: номер первой страницы (например, 1 по умолчанию)
last_page: номер last_page (например, количество подсписков)
номер страницы: получить номер страницы, на которой находится созданный мной объект
Пример:
settings.PAGE_LIMIT = 5
pk: 119
my_list_of_objects_code: <QuerySet ['a', 'aa', 'aaa', 'aaaa', 'aasza', 'abaaa', 'aqqq', 'asz', 'asza', 'awq', 'azazaza', 'azeaze', 'bgre', 'cdezf', 'da',...]>
pagination: [['a', 'aa', 'aaa', 'aaaa', 'aasza'], ['abaaa', 'aqqq', 'asz', 'asza', 'awq'], ['azazaza', 'azeaze', 'bgre', 'cdezf', 'da']...]
first_page: 1
last_page: 18
Проблема:
Когда я вызываю свою функцию, я получаю эту проблему :
Тип исключения: остановка
Файл «/home/Bureau/Projets/APP/my_app/src/my_app/views/main.py » в get_pagination 1830. page_number = (следующий (индекс для индекса, значение в перечислении (нумерация страниц), если pk в значении)) 1
Я не понимаю, как я могу решить эту проблему. Если мне нужно try/except
что я должен сделать?
Спасибо
Редактировать:
def get_pagination(my_list_of_objects, pk):
# if object doesn't exist, add id to list of objects
if pk not in my_list_of_objects:
my_list_of_objects.append(pk)
# Get the list of objects code splitted by PAGE_LIMIT sorted by code (default)
my_list_of_objects_code = MyModel.objects.values_list('code', flat=True).filter(id__in=my_list_of_objects)
pagination = [my_list_of_objects_code[x:x settings.PAGE_LIMIT] for x in range(0, len(my_list_of_objects_code), settings.PAGE_LIMIT)]
# Get first and last page number
first_page = 1
last_page = len(pagination)
try:
page_number = (next(index for index, value in enumerate(pagination) if MyModel.objects.get(pk=pk).code in value)) 1
except StopIteration:
page_number = 1
return pagination, first_page, last_page, page_number
Комментарии:
1. почему вы используете
next
?StopIteration
означает, что итератор исчерпал значения, поэтому не осталось никакого значения. Например. когда вы выполняете итерацию по списку из 2 элементов, при третьем вызовеnext
он подниметStopIteration
. Но в вашем случае вызовnext
не имеет смысла, если вам нужен только первый элемент (который вы получите, поскольку ваш итератор создается заново для каждого запроса)2. согласно приведенному выше комментарию, ваш итератор исчерпал все итерации и не может найти значение, соответствующее условию. Вам следует подумать о добавлении значения по умолчанию в свой
next
—page_number = next((conditional stuff....), 0)
обратите, 0
внимание на то, что после первого аргумента в next. Это остановит получение остановок, но оставит значение по умолчанию.3. @dirkgroten Я довольно хорошо понимаю, но я спрашиваю, как я могу получить значение
page_number
, которое соответствует индексу подсписка, содержащему конкретный код (у меня есть идентификатор, поэтому легко получить код).4.
pk
этоid
искомого объекта (целое число), ноvalue
это код объекта (строка), поэтому вы никогда не будете соответствовать требованиюpk in value
. Вы должны изменить свой список объектов на кортежи, содержащие идентификатор и код (.values_list(‘pk’, ‘code’)), чтобыvalue
в вашем тесте был кортеж, и вы могли проверитьpk == value[0]
5. но независимо от того, используете ли вы
next
или используете[0]
(для получения первого элемента), вам следуетtry...except
, потому что список может не содержать соответствующий объект (если pk не найден в БД)