Search code examples
pythondjangourlslugpermalinks

Model multiple field-lookup in Django 1.5


I have a model

class ModelName(models.Model):
    type = models.ForeignKey(AnotherModel)
    slug = models.SlugField(editable=False)

    class Meta:
        unique_together = (('type', 'slug'),)

    @models.permalink
    def get_absolute_url(self):
        return ('model_detail', (), {'type': self.type.slug, 'slug': self.slug})

and urls

urlpatterns = patterns('',
    url(r'^(?P<type>[-\w]+)/(?P<slug>[-\w]+)/$', ModelDetailView.as_view(), name='detail'),
)

and a DetailView

class ModelDetailView(DetailView):
    model = MyModel
    template_name = 'detail.html'

but I get the exception MultipleObjectsReturned because the slug isn't unique. I want the urls to be /type/slug/, so the model can contain two records with same slug, but different types, so urls could be /1/slug/ and /2/slug/ with different results. How can I tell the model to use both type and slug as lookup instead of just the slug?


Solution

  • You don't have to 'tell the model' to use the type and string fields -- it's the class based view you have to override.

    I suggest you override the get_queryset method, to restrict the queryset to objects of the correct type. An alternative would be to override the get_object method.

    class ModelDetailView(DetailView):
        model = MyModel
        template_name = 'detail.html'
    
        def get_queryset(self):
            """
            Restrict queryset to objects of the correct type
            """
            return MyModel.objects.filter(type_id=self.kwargs['type'])
    

    See the Django docs on dynamic filtering for more details.