Mapping the same first-level URL path to different models
I have two models with slug fields:
class Book(models.Model):
name = models.CharField(max_length=200)
slug = models.SlugField()
class Author(models.Model):
name = models.CharField(max_length=200)
slug = models.SlugField()
I would like to map them to the first-level path:
(r'^(?P<slug>开发者_如何学JAVA;[a-zA-Z0-9_-]+)/$', 'book_detail'),
(r'^(?P<slug>[a-zA-Z0-9_-]+)/$', 'author_detail'),
What's the best way to accomplish this without using the same function and returning either book or author based on the slug.
The best way would be to split it in the view:
r'^(?P<model>[a-zA-Z0-9_-]+)/(?P<slug>[a-zA-Z0-9_-]+)/$', 'some_detail')
and view:
def some_detail(request, model, slug):
try:
model = {'book':Book, 'author':Author}[model]
except KeyError:
raise Http404
item = get_object_or_404(model, slug=slug)
do_something_with(item)
...
edit: Oh, flat like that... that would be:
(r'^(?P<slug>[a-zA-Z0-9_-]+)/$', 'universal_detail'),
def universal_detail(request, slug):
try:
book = Book.objects.get(slug=slug)
return book_detail(request, book)
except Book.DoesNotExist:
pass
try:
author = Author.objects.get(slug=slug)
return author_details(request, author)
except Author.DoesNotExist:
raise Http404
def book_detail(request, book):
# note that book is a book instance here
pass
精彩评论