Django. Необходимо вывести 7 постов за текущую неделю, пустые даты заполнить шаблонной фразой
Всем доброго дня! Изучаю python и django. Поставил себе задачу, сделать для себя спортивный календарь для занятий, в дальнейшем API и подключение бота телеграмм. Идея простая, на определенные даты создавать тренировки (дата, название, сама тренировка). Выводить на страницу расписание на месяц, неделю.
На данный момент столкнулся со следующей проблемой.
Модель:
class Workout(models.Model):
title = models.CharField(max_length=200)
text = models.TextField()
pub_date = models.DateTimeField(auto_now_add=True)
date = models.DateField()
author = models.ForeignKey(
User,
on_delete=models.CASCADE,
related_name='workouts'
)
def __str__(self):
return self.title
Вьюшка:
def week(request):
template = 'workouts/week.html'
date = datetime.datetime.today()
week = date.strftime("%V")
workouts = Workout.objects.filter(date__week=week)
context = {
'workouts': workouts,
}
return render(request, template, context)
Шаблон:
{% block content %}
<div style="overflow: hidden;">
<div style="width: 1000%;">
{% for workout in workouts %}
<div style="float: left; width: 180px; margin-left: 5px;">
<div class="card">
<div class="card-header">
{{ workout.date }} <br> {{ workout.date|date:"l" }}
</div>
<div class="card-body">
<h6 class="card-title">{{ workout.title }}</h6>
<p class="card-text">{{ workout.text }}</p>
<a href="#" class="btn btn-primary">Подробно</a>
</div>
</div>
</div>
{% endfor %}
</div>
</div>
{% endblock content %}
Таким образом я вывожу на страницу занятия на текущую неделю, но я хочу, чтобы выводились и пустые дни. То есть если тренировки 3 (вт, чт, сб) - то получить следующее: 7 колонок на странице, в заголовках дата и день недели, ниже если нет тренировки - то текст -тренировок нет, если есть тренировка - то вывести название и тренировку.
Похоже, что нужно создать шаблон с 7 столбацами с каждым днем недели, но я не понимаю, как вывести данные в эти столбцы. Как проверять, что если в queryset сет есть данные на этот день - то выводим, если нет, то пишем занятий нет.
Наверное можно сравнивать даты в шаблоне и выводить данные, но скорее всего это не правильно.
Подозреваю, что можно во вьюшке каким то образом перебирать дни текущей недели, заполнять пустой день и передавать контекст, но моих знаний не хватает к сожалению.
Помогите, пожалуйста.
Ответы (2 шт):
Возможно, будет проще взять 7 queryset'ов на каждый день недели.
{% for w in workouts1 %}
<div class="card">
ваша тренировка в Пн
</div>
{% empty %}
тренировок в Пн нет. Добавить?
{% endfor %}
{% for w in workouts2 %}
<div class="card">
ваша тренировка в Вт
</div>
{% empty %}
тренировок в Вт нет. Добавить?
{% endfor %}
Передавай в шаблон не queryset а подготовленный список или словарь по которому затем будешь итерироваться в шаблоне.
def week(request):
template = 'workouts/week.html'
date = datetime.datetime.today()
week = date.strftime("%V")
workouts = Workout.objects.filter(date__week=week)
schedule = {
0: {"title": "Понедельник", "workout": []},
1: {"title": "Вторник", "workouts": []},
2: {"title": "Среда", "workouts": []},
3: {"title": "Четверг", "workouts": []},
4: {"title": "Пятница", "workouts": []},
5: {"title": "Суббота", "workouts": []},
6: {"title": "Воскресенье", "workouts": []},
}
for workout in workouts:
schedule[workout.date.weekday()]["workouts"].append(workout)
context = {
'schedule': schedule,
}
return render(request, template, context)
и дальше в шаблоне сначала итерируешься по дням, а затем внутри дня по тренировкам
{% block content %}
<div style="overflow: hidden;">
<div style="width: 1000%;">
{% for day in schedule %}
{{ day.title }}
{% for workout in day.workouts %}
<div style="float: left; width: 180px; margin-left: 5px;">
<div class="card">
<div class="card-header">
{{ workout.date }} <br> {{ workout.date|date:"l" }}
</div>
<div class="card-body">
<h6 class="card-title">{{ workout.title }}</h6>
<p class="card-text">{{ workout.text }}</p>
<a href="#" class="btn btn-primary">Подробно</a>
</div>
</div>
</div>
{% endfor %}
{% endfor %}
</div>
</div>
{% endblock content %}
В дальнейшем не составит труда переделать отображение недели на отображение месяца