Замена num_latest общими представлениями на основе классов на основе даты?

Я перешел на Django 1.3, чтобы получить нумерацию страниц для моих общих представлений на основе даты. Это отлично работает, однако есть страница, на которой я хочу указать определенное количество элементов, но не хочу, чтобы она разбивалась на страницы. Например, вернуть первые 5 записей новостей.

В 1.2 у нас было num_latest, которое мы могли поместить в наш информационный словарь, чтобы получить последние элементы. Кажется, этого не существует с новыми универсальными представлениями на основе классов.

Я мог бы установить для paginate_by значение 5 и просто не использовать ссылки на страницы в шаблоне, но тогда люди все равно смогут видеть старые записи, вбивая URL-адрес вручную (чего я не хочу). Кроме того, я не хочу, чтобы Django настраивал нумерацию страниц, которую я не собираюсь использовать.

Изменить: это строка urlconf, которую я сейчас использую:

url(r'^$', 
    ArchiveIndexView.as_view(
        model = Entry,
        context_object_name = 'entry_list',
        template_name = 'news/news.html',
        date_field = 'published',
    ), name = 'archive_index'
),

Дальнейшее редактирование: Попытка переопределить get_dated_queryset Я использовал этот фрагмент кода в сочетании с urlconf, как указано выше, но с новым представлением под названием:

class MainIndex(ArchiveIndexView):
    def get_dated_queryset(self):
        return Entry.objects.all()[:2]

Я получаю почти ту же ошибку, что и в комментариях: невозможно изменить порядок запроса после того, как фрагмент был взят.


person Tom Carrick    schedule 12.09.2011    source источник


Ответы (2)


Вместо этого попробуйте переопределить это:

def get_dated_items(self):
    date_list, items, extra_context = super(MainIndex, self).get_dated_items()
    return (date_list, items[:2], extra_context)
Примечание: эта реализация может оставить date_list несовместимым с набором запросов items после того, как последний будет нарезан. Я думаю, что для исправления этого вам также потребуется восстановить date_list. см. реализацию BaseArchiveIndexView.get_dated_items в SVN для более подробной информации: http://code.djangoproject.com/browser/django/trunk/django/views/generic/dates.py. Что-то вроде этого может работать:
def get_dated_items(self):
    date_list, items, extra_context = super(MainIndex, self).get_dated_items()
    items = items[:2]
    date_list = self.get_date_list(items, 'year')
    if not date_list:
        items = items.none()
    return (date_list, items, extra_context)
но если это работает без этого, я бы не стал его трогать, потому что это выглядит слишком грязно.

person akonsu    schedule 12.09.2011
comment
К сожалению, нет. Я уже пробовал просто нарезать набор запросов следующим образом: queryset = Entry.objects.all()[:5], однако это дает мне следующую ошибку: Невозможно отфильтровать запрос после того, как фрагмент был взят. больше вещей, сделанных после среза. - person Tom Carrick; 12.09.2011
comment
Вы используете производную смесь BaseDayArchiveView? - person akonsu; 12.09.2011
comment
Не для этого URL. Я отредактировал свой исходный пост, чтобы показать urlconf, который я сейчас использую для соответствующего представления. - person Tom Carrick; 12.09.2011
comment
Хм. Похоже, это сработает, но выглядит очень грязно, и, судя по всему, мне было бы лучше просто создать собственное представление или использовать paginate_by и просто не использовать нумерацию страниц. Вероятно, меньше кода тоже. Я отмечу это как ответ, если никто не придумает лучшую идею. Спасибо. - person Tom Carrick; 12.09.2011
comment
все, что работает для вас. Я думаю, что подклассы — это подход к дизайну, к которому стремится django. другими словами, если вы хотите расширить функциональность представления, вы создаете его подкласс, тем самым создавая собственное представление. см., например, здесь: https://docs.djangoproject.com/en/dev/topics/class-based-views/#extending-generic-views - person akonsu; 12.09.2011
comment
Я пробовал этот метод (который кажется правильным способом сделать это). Я начал с того, что полностью переопределил функцию, но даже это не сработает, ошибка, как указано выше. - person Tom Carrick; 12.09.2011
comment
попробуйте вместо этого переопределить get_queryset(), но в вашей реализации сначала вызовите базовую реализацию, а затем нарежьте ее. это просто вопрос поиска правильного места для нарезки набора запросов. - person akonsu; 12.09.2011
comment
Ранее я пытался переопределить get_queryset() и та же ошибка. Можете ли вы уточнить, что вы имеете в виду под вызовом базовой реализации? Я не уверен, что понимаю, что вы имеете в виду. Можете ли вы дать строку или две кода? - person Tom Carrick; 12.09.2011
comment
Это работает идеально, спасибо за вашу помощь и терпение. - person Tom Carrick; 12.09.2011
comment
Кажется, все работает нормально, но мой набор данных очень мал. Я буду иметь это в виду, если у меня возникнут проблемы. Спасибо. - person Tom Carrick; 12.09.2011

Я сам столкнулся с этой проблемой. Я обнаружил, что использование ListView (вместо ArchiveIndexView) для этого сэкономило мне время и нервы.

Для вашего первого фрагмента кода разница будет следующей:

from django.views.generic import ListView


url(r'^$', 
    ListView.as_view(
        model = Entry,
        context_object_name = 'entry_list',
        template_name = 'news/news.html',
        queryset=Entry.objects.all().order_by("-published")[:2],
    ), name = 'archive_index'
),
person stickwithjosh    schedule 26.07.2013