Допустим, у меня есть несколько моделей, которые наследуются от базового класса Animal. Я могу использовать общие представления и направлять Cat/12 в подробное представление, а Dod/10 в то же самое подробное представление с другим контекстом. Но я хотел бы получить имя модели из URL-адреса, чтобы мне не нужно было определять маршрут.
У меня есть что-то вроде этого:
url(r'^cat/(?P<slug>[-\w]+)/$',
DetailView.as_view(
queryset=Cat.objects.filter(),
model=Cat,
context_object_name='animal',
template_name='animal/detail.html'),
name='detail'),
url(r'^dog/(?P<slug>[-\w]+)/$',
DetailView.as_view(
queryset=Dog.objects.filter(),
model=Dog,
context_object_name='animal',
template_name='animal/detail.html'),
name='detail'),
...
Очевидно, что это слишком много повторяющегося кода. Я бы предпочел сделать что-то вроде этого:
url(r'^?P<my_animal>\w+/(?P<slug>[-\w]+)/$',
DetailView.as_view(
queryset=my_animal.objects.filter(),
model=my_animal,
context_object_name='animal',
template_name='animal/detail.html'),
name='detail'),
...
Я могу сделать это?
ИЗМЕНИТЬ
Вот что у меня получилось благодаря помощи Дарвина. Это позволяет избежать if/else для получения имени модели:
class AnimalDetailView(DetailView):
context_object_name='animal'
template_name='animals/detail.html'
def dispatch(self, request, *args, **kwargs):
my_animal = kwargs.get('my_animal', None)
self.model = get_model('animals',my_animal.capitalize())
try:
ret = super(AnimalDetailView, self).dispatch(request, *args, **kwargs)
except AttributeError:
raise Http404
return ret
def get_queryset(self):
return self.model.objects.filter()
В следующий раз, когда у меня возникнет вопрос о наследовании, я проконсультируюсь с Дарвином! Смешной