Разделение объектов словаря

#python #django #django-views #django-queryset

Вопрос:

Я создаю приложение для блога , и с тех пор я создал queryset его showing blog date and likes каждый день blog date , но оно отображается, dictionary и я пытаюсь показать оба экземпляра по-разному в таблице, как.

Дата в Блоге Нравится
20 сентября. 6 Лайков
21 сентября. 2 Лайка
22 сентября. 4 Лайка

Но это показывает, как :-

 ({20: 6},{21: 2},{22: 4})
 

models.py

 class BlogPost(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    title = models.CharField(max_length=30, default='')
    date = models.DateTimeField(auto_now_add=True)

class Likes(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    blogpost_like = models.ForeignKey(BlogPost, on_delete=models.CASCADE)
 

views.py

 from django.db.models.functions import ExtractDay
from collections import Counter

def page(request):
    blogpost = get_object_or_404(BlogPost,pk=pk)

    totals = blogpost.likes_set.filter(
        blogpost_like__date=blogpost.date,
        ).annotate(
            date=ExtractDay('blogpost__date'),
        ).values(
            'date'
        ).annotate(
            n=Count('pk')
        ).order_by('date').values()

    results = Counter({d['date']: d['n'] for d in totals})

    context = {'results':results}
    return render(request, 'page.html', context)
 

Что я пробовал ? :-

  • Я пытался
 lists = [{'id': blog.date, 'name': blog.n} for blog in results ]
 

Но он показывает только дату, как 24 не нравится.

  • чем я пытался
 json.dumps(list(results ))
 
  • чем я пытался
 from calendar import monthrange

__, ds = monthrange(blogpost.date)
finalSecond = [data[i] for i in range(1, ds 1)]
 

Но это показало

monthrange() отсутствует 1 необходимый позиционный аргумент: «месяц»

Я пробовал много раз, но это все еще не работает.

Любая помощь была бы очень признательна. Спасибо

Ответ №1:

Вы можете использовать TruncDate для получения даты:

 from django.db.models import Count
from django.db.models.functions import TruncDate

totals = blogpost.likes_set.filter(
    blogpost__date=blogpost.date,
).values(
    date=TruncDate('blogpost__date')
).annotate(
    n=Count('pk')
).order_by('date') 

Если вы передадите это в контекст, вы сможете отобразить его с помощью:

 <table>
  <thead>
    <th>Blog Date</th><th>Likes</th>
  </thead>
  <tbody>
    {% for item in totals %}
      <tr>
        <td>{{ item.date|date:"F, d" }}</td><td>{{ item.n }}</td>
      </tr>
    {% endfor %}
  </tbody>
</table> 

Ответ №2:

 {d['date']: d['n'] for d in totals}
 

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

 return render(request, 'page.html', {"results": totals})
 

Таким образом, ваши данные легко попадают в шаблон. Тогда вашему html-шаблону просто нужно повторить результаты:

 {% for result in results %}
<tr>
  <td>result.date</td><td>result.n</td>
</tr>
{% endfor %}
 

Комментарии:

1. Я сделал, как вы сказали, но это видно только date так, как 24 в template loop

2. Я сделал шаблон более четким