Как получить доступ к свойствам отношений "один-ко-многим" в шаблонах Django?
Я очень новичок в Python & Django. Я создаю личный дневник с довольно простыми свойствами, такими как месяцы и записи.
models.py
class Month(models.Model):
id = models.AutoField(primary_key=True)
month_name = models.CharField(verbose_name="Month", max_length=20, unique=True)
year_number = models.IntegerField(verbose_name="Year")
featured_img = models.ImageField(verbose_name="Featured", upload_to='diary/featured_img', default=False)
class Meta:
verbose_name = "Month"
ordering = ['-year_number', 'month_name']
def __str__(self):
return '%s, %s' % (self.month_name, self.year_number)
class Entry(models.Model):
id = models.AutoField(primary_key=True)
title = models.CharField(max_length=200)
content = models.TextField()
month = models.ForeignKey('Month', on_delete=models.RESTRICT, null=True)
img = models.ImageField(verbose_name="Image", upload_to='diary/entry_img', default=False)
date_created = models.DateTimeField(verbose_name="Date", default=timezone.now)
def __str__(self):
return self.title
class Meta:
verbose_name_plural = "Entries"
ordering = ['-date_created']
Я пытаюсь создать простую веб-страницу, которая отображает месяцы в виде списка, и когда я нажимаю на месяц, я получаю записи в подробном представлении. Я выполнил первый шаг, но не могу понять, как получить доступ к отношениям "один-ко-многим" между моделью Month и Entry в шаблонах Django. Я хочу отобразить страницу со всеми объектами модели Month, и когда пользователь нажимает на определенный месяц, скажем "December", Django возвращает все записи, у которых объект month определен как December.
Это прекрасно работало в админке, где я вставил метод TabularInLine и мог видеть все записи за определенный месяц, но я не могу понять, как это сделать в шаблонах и представлениях.
admin.py
class EntryInLine(admin.TabularInline):
model = Entry
class MonthAdmin(admin.ModelAdmin):
inlines = [EntryInLine]
admin.site.register(Month, MonthAdmin)
views.py
class MonthListView(generic.ListView):
model = Month
context_object_name = 'month_list'
template_name = 'diary/month.html'
class MonthDetailView(generic.DetailView):
model = Entry
context_object_name = 'entries_list'
template_name = 'diary/entries.html'
def index(request):
month = Month.objects.all()
entry = Entry.objects.all()
context = {
'month': month,
'entry': entry,
}
return render(request, 'index.html', context=context)
urls.py
urlpatterns = [
path('', views.index, name='index'),
path('month/', views.MonthListView.as_view(), name='month'),
path('month/<int:pk>', views.MonthDetailView.as_view(), name='entries'),
]
month.html
{% extends "base.html" %}
{% block title %}<title>Months</title>{% endblock %}
{% block content %}
<h1>Month</h1>
{% if month_list %}
<ul>
{% for month in month_list %}
<li>
<a href="month.get_absolute_url()">{{ month.month_name }}</a>
</li>
{% endfor %}
</ul>
{% else %}
<p>There are no months to display</p>
{% endif %}
{% endblock %}
entries.html
{% extends "base.html" %}
{% block title %}<title>Entries</title>{% endblock %}
{% block content %}
{% if entries_list %}
{% for entry in entries_list %}
<h3>{{ entry.title }}</h3>
<p>{{ entry.date_created }}</p>
<p>{{ entry.content }}</p>
{% endfor %}
{% else %}
<p>There are no entries in this month.</p>
{% endif %}
{% endblock %}
Я знаю, что проблема, вероятно, в добавлении модели Entry в DetailView и сопоставлении url, но я не смог найти хороший ресурс в Интернете, чтобы объяснить, что именно не так.
У меня получилось! Добавил функцию get_context_data в MonthDetailView и теперь все работает!
class MonthDetailView(generic.DetailView):
model = Entry
context_object_name = 'entries_list'
template_name = 'diary/entries.html'
def get_context_data(self, **kwargs):
context = super(MonthDetailView, self).get_context_data(**kwargs)
context['entries_list'] = Entry.objects.filter(month=self.kwargs['pk'])
return context