Архив сообщений на основе года / месяца - PullRequest
6 голосов
/ 29 октября 2009

Я новичок в Django и запустил приложение, я сделал модели, представления, шаблоны, но я хочу добавить какой-то архив в нижней части страницы, что-то вроде этого http://www.flickr.com/photos/ionutgabriel/3990015411/.

Итак, я хочу перечислить все годы, а рядом с ними все месяцы этого года. Месяцев, у которых есть посты, чтобы быть ссылками, а других нет. Также я хочу перевести названия месяцев, потому что они мне нужны на румынском языке.

То, что я сделал до сих пор:

на мой взгляд:

def archive(request): 
    arch = Post.objects.dates('date', 'month', order='DESC') 

    archives = {} 
    for i in arch: 
        tp = i.timetuple() 
        year = tp[0] 
        month = tp[1] 
        if year not in archives: 
            archives[year] = [] 
            archives[year].append(month) 
        else: 
            if month not in archives[year]: 
                archives[year].append(month) 
    return render_to_response('blog/arhiva.html', {'archives':archives}) 

и в моем шаблоне:

    {% for years, months in archives.items %} 
                    {{ years }} 
                    {% for month in months %} 
                   <a href="{{ years }}/{{ month }}">{{ month }}</a> 
                    {% endfor %} 
            <br /> 
                {% endfor %} 

это возвращает что-то вроде:

       2008               10 
       2009               10               9 
       2007               10 

но я не могу их отсортировать вообще ... по годам или по чему-либо, а также я не знаю, как добавить все месяцы (названия), я хочу, чтобы они были такими:

   2009 Ian Feb Mar Apr Mai Iun Iul Aug Sept Oct Noi Dec       
   2008 Ian Feb Mar Apr Mai Iun Iul Aug Sept Oct Noi Dec
   2007 Ian Feb Mar Apr Mai Iun Iul Aug Sept Oct Noi Dec

со ссылкой на месяцы, у которых есть записи.

Спасибо за вашу помощь!

p.s. извините за мой английский

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

   2009 Ian Feb Mar Apr Mai Iun Iul Aug Sept Oct Noi Dec       
   2008 Ian Feb Mar Apr Mai Iun Iul Aug Sept Oct Noi Dec
   2007 Ian Feb Mar Apr Mai Iun Iul Aug Sept Oct Noi Dec

все, что я могу получить от arch = Post.objects.dates('date', 'month', order='DESC')

с

{{ archives }} в шаблоне что-то вроде:

[datetime.datetime(2009, 10, 1, 0, 0), datetime.datetime(2009, 9, 1, 0, 0),
 datetime.datetime(2008, 10, 1, 0, 0), datetime.datetime(2007, 10, 1, 0, 0)]

тогда я попробовал цикл:

{% for archive in archives %}

{{ archive }} <br />

{% endfor %}

и получил:

2009-10-01 00:00:00 
2009-09-01 00:00:00 
2008-10-01 00:00:00 
2007-10-01 00:00:00 

После этого попробовал что-то вроде этого:

{% for archive in archives %}

{{ archive|date:"Y: m" }} <br />

{% endfor %}

и получил:

2009: 10 
2009: 09 
2008: 10 
2007: 10 

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

Есть идеи?

Заранее спасибо!

Ответы [ 3 ]

12 голосов
/ 29 октября 2009

Во-первых, строки формата datetime приведены в django документах . Я думаю, что вы хотите заглавную букву вместо строчной буквы "М".

Поскольку вы хотите отображать все 12 месяцев в году, даже если только у некоторых есть сообщения, мы создадим объект archives для передачи в шаблон. Я решил использовать словарь, где

  • ключи - это годы
  • значения представляют собой список из 12 [datetime, bool] пар, где datetime представляет месяц, а bool - True, если в этом месяце есть сообщения.

Вот как мы строим archives объект в представлении.

from datetime import date

def archive(request):
    arch = Post.objects.dates('date', 'month', order='DESC')

    archives = {}

    for i in arch:
        year = i.year
        month = i.month
        try:
            archives[year][month-1][1]=True
        except KeyError:
            # catch the KeyError, and set up list for that year
            archives[year]=[[date(y,m,1),False] for m in xrange(1,13)]
            archives[year][month-1][1]=True

    return render_to_response('blog/arhiva.html', 
              {'archives':sorted(archives.items(),reverse=True)})

В шаблоне мы перебираем месяцы для каждого года и при необходимости отображаем ссылку.

{% for year, month_list in archives %}
  {{ year }} archives: 
  {% for month, has_link in month_list %}
    {% if has_link %}<a href="/{{ month.year }}/{{ month.month }}/">{% endif %}
      {{ month|date:"M" }}
    {% if has_link %}</a>{% endif %}
  {% endfor %}
{% endfor %}

Я не проверил весь код, поэтому может быть пара ошибок. Было бы лучше использовать шаблон URL-тега для ссылки вместо жесткого кодирования формата URL-адреса. У меня есть ощущение, что мой ответ может быть слишком сложным, но я потратил некоторое время, набирая его, так что я могу также поделиться им с миром.


Интернационализация

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

Сказав, что, если вы хотите отобразить месяцы только на румынском языке, вот ужасный способ сделать это.

Сначала добавьте следующую строку в начало вашей функции архива в представлении.

rom_months = ['Ian', 'Feb', 'Mar', 'Apr', 'Mai', 'Iun', 
              'Iul', 'Aug', 'Sept', 'Oct', 'Noi', 'Dec']

Затем подставьте следующую строку в ваше представление

archives[year]=[[date(y,k+1,1),False,rom] for k, rom in enumerate(rom_months)]

Наконец замените следующее в шаблоне

...
{% for month, has_link, rom_month in month_list %}
  {% if has_link %}<a href="/{{ month.year }}/{{ month.month }}/">{% endif %}
  {{ rom_month }}
...
2 голосов
/ 30 октября 2009

Хорошо ... итоговый код, который работает для меня:

в поле зрения:

 rom_months = ['Ian', 'Feb', 'Mar', 'Apr', 'Mai', 'Iun', 
'Iul', 'Aug', 'Sept', 'Oct', 'Noi', 'Dec']

def arhiva(request):
    arch = Post.objects.dates('data', 'month', order='DESC')

    archives = {}

    for i in arch:
        year = i.year
        month = i.month
        try:
            archives[year][month-1][1] = True
        except KeyError:

            archives[year]=[[datetime.date(year,k+1,1),False,rom] for k, rom in enumerate(rom_months)]
            archives[year][month-1][1] = True

    return render_to_response('blog/arhiva.html', {'archives':sorted(archives.items(),reverse=True)})

и в шаблоне:

{% for year, month_list in archives %}
    {{ year }} Arhive: 
    {% for month, has_link, rom_month in month_list %}
        {% if has_link %}<a href="/{{ month.year }}/{{ month.month }}/">{% endif %}
             {{ rom_month }}
        {% if has_link %}</a>{% endif %} 
    {% endfor %}
    <br />
{% endfor %}

и результат:

2009 Arhive: Ian Feb Mar Apr Mai Iun Iul Aug Sept Oct Noi Dec 
2008 Arhive: Ian Feb Mar Apr Mai Iun Iul Aug Sept Oct Noi Dec 
2007 Arhive: Ian Feb Mar Apr Mai Iun Iul Aug Sept Oct Noi Dec 
2003 Arhive: Ian Feb Mar Apr Mai Iun Iul Aug Sept Oct Noi Dec 

Большое спасибо еще раз за помощь. Ты лучший! Я n00b! :)

2 голосов
/ 29 октября 2009

Возможно, вы захотите начать с универсального представления и создать его.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...