DetailView与年和pk在url

时间:2014-03-25 11:27:21

标签: django django-urls

我试图制作一个网址设置,根据一年(而不是月和日)和pk显示详细信息页面。像这样/YEAR/ISSUE/

这就是我的尝试:

我的model.py:

class Mag(models.Model):
    name = models.CharField(max_length=500)
    issue = models.PositiveIntegerField()  
    pub_date = models.DateTimeField()


    unique_together = ("pub_date", "issue")

    def __unicode__(self):
        return self.name        

    @models.permalink        
    def get_absolute_url(self):
            creation_date = timezone.localtime(self.pub_date)
            return ('mag_detail', (), {
                'year': creation_date.strftime('%Y'),
                'pk': self.issue})

我的views.py:

class MagDetail(DateDetailView):

    model = Mag
    pk_url_kwarg='pk'
    date_field='pub_date'

我的urls.py

urlpatterns = patterns('',
    url(r'^(?P<year>\d{4})/(?P<pk>\d+)/$', MagDetail.as_view(), name='mag_detail'),
)

但是当我尝试2014/1这样的网址时,我收到month is not specified的错误。

是否可以使用DateDetailView执行我想要的操作,还是需要查看其他类?

2 个答案:

答案 0 :(得分:3)

如果您使用标准DetailView并覆盖get_object()方法,如下所示:

from django.shortcuts import get_object_or_404

class MagDetail(DetailView):
    model = Mag

    def get_object(self):

        obj = get_object_or_404(
            self.model, 
            pk=self.kwargs['pk'], 
            pub_date__year=self.kwargs['year'])

        return obj

答案 1 :(得分:1)

DateDetailView需要格式year/month/day

作为一种通用的方法,如果你将项目中的这种视图用于除了Mag之外的其他模型,你可以从中派生出来并改变get_object方法,大致如下:

class YearDetailView(DateDetailView):
    def get_object(self, queryset=None):
        """
        Get the object this request displays.
        """
        year = self.get_year()

        # Use a custom queryset if provided
        qs = queryset or self.get_queryset()

        if not self.get_allow_future() and int(year) > datetime.today().year:
            raise Http404(_("Future %(verbose_name_plural)s not available because 
                            %(class_name)s.allow_future is False.") % {
                                'verbose_name_plural': qs.model._meta.verbose_name_plural,
                                'class_name': self.__class__.__name__,
                          })

        lookup_args = {"%s__year" % self.get_date_field(): year}
        qs = qs.filter(**lookup_args)

        return super(BaseDetailView, self).get_object(queryset=qs)

class MagDetail(YearDetailView): # note that we derive from our new class!
    model = Mag
    pk_url_kwarg='pk'
    date_field='pub_date'