samedi 26 juillet 2014

Django - DetailView avec an et pk en url - Stack Overflow


Im trying to make a url setup that would display a detail page based on just a year (not month and day), and a pk. like this /YEAR/ISSUE/


This is what I have tried:


My 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})

My views.py:


class MagDetail(DateDetailView):

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

My urls.py


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

But when I try a url like 2014/1, I get an error that month is not specified.


Is it possible to do what I want with DateDetailView, or do I need to look another class?




What if you use a standard DetailView and override the get_object() method, like this:


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



The DateDetailView expects the format of year/month/day


As a general approach, if you will be using this kind of view in your project for other models than Mag alone, you can derive from it though and change the get_object method, roughly like that:


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'


Im trying to make a url setup that would display a detail page based on just a year (not month and day), and a pk. like this /YEAR/ISSUE/


This is what I have tried:


My 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})

My views.py:


class MagDetail(DateDetailView):

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

My urls.py


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

But when I try a url like 2014/1, I get an error that month is not specified.


Is it possible to do what I want with DateDetailView, or do I need to look another class?



What if you use a standard DetailView and override the get_object() method, like this:


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


The DateDetailView expects the format of year/month/day


As a general approach, if you will be using this kind of view in your project for other models than Mag alone, you can derive from it though and change the get_object method, roughly like that:


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'

0 commentaires:

Enregistrer un commentaire