我有Django模型描述特定日期对这些地方的地方和访问:
from django.db import models
class Place(models.Model):
# ...
name = models.CharField(max_length=255)
class Visit(models.Model):
# ...
place = models.ForeignKey('Place', blank=False)
visit_date = models.DateField(blank=False)
我想显示一年内访问过的所有地方,因此我尝试使用YearArchiveView
date_field
跨越与访问的关系:
from django.views.generic import YearArchiveView
from myapp.models import Place
class PlaceYearArchiveView(YearArchiveView):
date_field = 'visit__visit_date'
model = Place
然而,这让我感到兴奋,并且#34; Place没有名为' visit__visit_date'"。
使用此视图的最简单方法是使用类似的查询集(假设d1
和d2
是一年中的第一天和最后一天) :
Place.objects.filter(visit__visit_date__gte=d1, visit__visit_date__lte=d2).distinct()
我可以使用标准ListView
并编写我自己的get_queryset()
方法,但如果我可以将其基于YearArchiveView
,那似乎更好。
答案 0 :(得分:1)
ListView
应该足以满足您的需求,因为YearArchiveView
通常用于日期层次结构,在您的情况下,下一级别是Place
。
如果您确实想使用YearArchiveView
,则需要... mmm ...稍微玩一下。以下是两个选项。
假设以下访问模型(经过一些小的改动):
class Visit(models.Model):
place = models.ForeignKey(Place, related_name='visits')
date = models.DateField()
选项1:使用regroup
模板标记:
views.py
:
class PlaceYearArchiveView(YearArchiveView):
date_field = 'date'
model = models.Visit
make_object_list = True
ordering = ('place', 'date')
visit_archive_year.html
:
<h1>{{ year.year }}</h1>
<ul>
{% regroup object_list by place as grouped %}
{% for group in grouped %}
<li>
{{ group.grouper.name }}
({% for visit in group.list %}{{ visit.date }}{% if not forloop.last %}, {% endif %}{% endfor %})
</li>
{% endfor %}
</ul>
选项2:修改`get_dated_items()&#39;
views.py
:
class PlaceYearArchiveView(YearArchiveView):
date_field = 'date'
make_object_list = True
model = models.Visit
ordering = 'place'
def get_dated_items(self):
items, qs, info = super().get_dated_items()
return items, qs.distinct('place'), info
visit_archive_year.html
:
<h1>{{ year.year }}</h1>
<ul>
{% for v in object_list %}
<li>@{{ v.date }}: {{ v.place.name }}</li>
{% endfor %}
</ul>