Django基于日期的ArchiveView与ForeignKey date_field

时间:2017-03-08 15:28:30

标签: django django-views

我有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'"。

使用此视图的最简单方法是使用类似的查询集(假设d1d2是一年中的第一天和最后一天) :

Place.objects.filter(visit__visit_date__gte=d1, visit__visit_date__lte=d2).distinct()

我可以使用标准ListView并编写我自己的get_queryset()方法,但如果我可以将其基于YearArchiveView,那似乎更好。

1 个答案:

答案 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>