2013-04-24 1 views
3

기본 클래스 인 Animal에서 상속받은 일부 모델이 있다고 가정 해 봅시다. 일반 뷰를 사용하고 Cat/12를 세부 뷰에, Dod/10을 다른 세부 컨텍스트와 동일한 세부 뷰에 라우팅 할 수 있습니다. 하지만 경로를 정의 할 필요가 없도록 URL에서 모델 이름을 얻고 싶습니다.Django - 일반 뷰에 대한 매개 변수로 모델 이름을 전달하십시오.

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() 

다음에 나는 상속에 대해 질문 할 것이고, 나는 다윈과상의 할 것입니다! LOL

답변

4

DetailView에서 상속 받고 디스패치 메서드를 재정 의하여 사용자를 빌드 할 수 있습니다.

class AnimalDetailView(DetailView): 
    context_object_name='animal' 
    template_name='animal/detail.html' 

    def dispatch(self, request, *args, **kwargs): 
     my_animal = kwargs.get('my_animal', None) 
     if my_animal == 'dog': 
      self.model = Dog 
     elif my_animal == 'cat': 
      self.model = Cat 

     return super(AnimalDetailView, self).dispatch(request, *args, **kwargs) 

    def get_queryset(self): 
     return self.model.objects.filter() 

이 같은 URLPATTERN 사용 :

url(r'^?P<my_animal>\w+/(?P<slug>[-\w]+)/$', AnimalDetailView.as_view()) 

을 편집 :이 같은 뭔가 자신의 규칙마지막으로 'as_view()'메서드 만 사용하여 뷰 클래스를 인스턴스화 할 수 없기 때문에 실수를했습니다. 새로운 접근법을 시도해보십시오. 이것이 도움이 될 수 있다고 생각합니다.

+0

도움이되지 않는 오류 종류 :'이 메서드는 뷰 클래스에서만 사용할 수 있습니다. . –

+0

코드를 다시보십시오. 처리기는 그 안에 있지 않고 AnimalDetailView 다음에 정의됩니다. – Darwin

+0

AnimalDetailView 클래스 외부에서 정의했습니다. 내 views.py에서'animals.views 가져 오기 처리기 '를 사용하여 가져 오기 –

1

예, 명명 된 매개 변수 귀하의 URL을 will automatically be passed as keyword arguments to your views,에서 (즉 ?P<my_animal>) :

The key part to making this [Class Based Views] work is that when class-based views are called, various useful things are stored on self; as well as the request (self.request) this includes the positional (self.args) and name-based (self.kwargs) arguments captured according to the URLconf.

은 그래서 당신은보기에 self.kwargs['my_animal']로에 액세스 할 수 있습니다.

당신은 look at the __init__ method of BaseDetailView (이 DetailView 상속에서) 당신은이 kwargs을 복용하고 인스턴스 속성에 할당됩니다하고있는 모든, 그래서 당신은 쉽게 다음 할 수있는 것을 볼 수 있습니다 경우

url(r'^?P<model>\w+/(?P<slug>[-\w]+)/$',... 

과 보기는 자동으로 URL에 전달 된 값을 self.model에 할당해야합니다. 당연히 신중해야하며 여기서 입력을 확인해야합니다. 사용자가 지정한 모델에서 객체를 동적으로 잡는 좋은 방법입니다.

+0

달콤하지만 잘못하고 있습니다. urls.py에 'name'my_plant 'not defined'가 있습니다. –