Разбиение на страницы Django Generic object_list. Добавление вместо замены аргументов

У меня возникли проблемы с разбивкой на страницы общей функции object_list django, которая на самом деле не является достаточно «умной», чтобы компенсировать мою глупость.

Я пытаюсь сделать URL-адрес для списка с необязательными аргументами для номера страницы и категории. URL-адрес в urls.py выглядит так:

url(r'^all/(?:(?P<category>[-\w]+)/page-(?P<urlpage>\d+))?/$', views.listing, ),

Аргументы категории и URL-адреса являются необязательными из-за дополнительных "(?:)?" вокруг них, и это прекрасно работает. views.listing — это функция-оболочка, выглядящая так (я не думаю, что здесь возникает моя проблема):

def listing(request,category="a-z",urlpage="1"):
extra_context_dict={}
if category=="a-z":
    catqueryset=models.UserProfile.objects.all().order_by('user__username')
elif category=="z-a":
    catqueryset=models.UserProfile.objects.all().order_by(-'user__username')
else:
    extra_context_dict['error_message']='Unfortunately a sorting error occurred, content is listed in alphabetical order'
    catqueryset=models.UserProfile.objects.all().order_by('user__username')
return object_list(
                    request,
                    queryset=catqueryset,
                    template_name='userlist.html',
                    page=urlpage,
                    paginate_by=10,
                    extra_context=extra_context_dict,
                    )

В моем шаблоне userlist.html у меня есть ссылки, выглядящие так (я думаю, здесь и заключается настоящая проблема):

{%if has_next%}
  <a href=page-{{next}}>Next Page> ({{next}})</a>
{%else%}

Вместо замены аргумента страницы в моем URL-адресе ссылка добавляет к URL-адресу еще один аргумент страницы. URL-адреса в конечном итоге выглядят так: "/all/a-z/page-1/page-2/

На самом деле неудивительно, что это то, что происходит, но отсутствие страницы в качестве необязательного аргумента действительно работает, и Django заменяет старую часть страницы URL-адреса.

Я бы предпочел это решение DRYer (по крайней мере, я так думаю), но, похоже, оно не работает. Будем очень признательны за любые советы, как это можно решить с помощью лучших тегов urls.py или template.

(также, пожалуйста, извините за неродной английский и код, переведенный на лету. Любые отзывы о том, является ли это хорошим или необоснованным вопросом о переполнении стека, также с удовольствием принимаются)


person Tobias    schedule 08.10.2010    source источник


Ответы (3)


Здесь вы используете относительные URL-адреса, так что это не имеет никакого отношения к Django. Вы можете заменить ссылку на:

<a href="/all/a-z/page-{{ next }}">Next Page> ({{ next }})</a>

и все было бы хорошо, за исключением того факта, что у вас была бы хрупкая ссылка в вашем шаблоне, которая сломается, как только вы измените свой urls.py, и она не будет работать, если category не окажется a-z.

Вместо этого используйте встроенный в Django тег url.

<a href="{% url views.listing category next %}">Next Page> ({{ next }})</a>

Чтобы это работало, вам нужно будет передать свою категорию в extra_context_dict, который вы создаете в первой строке вашего кода представления:

extra_context_dict = { 'category': category }
person Dominic Rodger    schedule 08.10.2010
comment
Хотя все предложенные решения будут работать (спасибо всем), ваше не только решило мою проблему, но и дало мне гораздо лучший способ использования django в целом. Спасибо Доминик! КСТАТИ. Я использую именованные URL-адреса вместо именованных представлений, есть ли причина, по которой это кажется таким непопулярным среди разработчиков django? РЕДАКТИРОВАТЬ: слишком медленно редактировать первый :( - person Tobias; 08.10.2010
comment
@Tobias - рад, что смог помочь - спасибо! Я не уверен, почему (и действительно ли) именованные URL-адреса непопулярны среди разработчиков Django — я все время использую именованные URL-адреса. Возможно, задайте об этом отдельный вопрос (и включите доказательства того, что они непопулярны!). - person Dominic Rodger; 10.10.2010

/all/a-z/page-1/page-2/ это то, что указано в источнике или куда ведет ссылка? Я предполагаю, что строка «страница-2» добавляется браузером к текущему URL-адресу. Вы должны начать с URL-адреса с /, чтобы указать полный путь.

Вероятно, вам следует добавить категорию в extra_context и сделать:

 <a href="/all/{{category}}/page-{{next}}">next page ({{next}})</a>
person OmerGertel    schedule 08.10.2010

«Вместо замены аргумента страницы в моем URL-адресе ссылка добавляет к URL-адресу еще один аргумент страницы. В итоге URL-адреса выглядят так: «/all/a-z/page-1/page-2/»

это потому, что

'<a href=page-{{next}}>Next Page> ({{next}})</a>'

ссылки на страницу относительно текущего URL-адреса, а текущий URL-адрес уже содержит /page-1/.

я не уверен, как работает отсутствие страницы в качестве необязательного аргумента, и Django заменяет старую страницу-часть URL-адреса

одна вещь, которую я предлагаю, вместо определения относительного URL-адреса определяет абсолютный URL-адрес

'<a href="/<other-part-of-url>/page-{{ next }}">Next Page> ({{ next }})</a>'
person Ashok    schedule 08.10.2010