2011-12-13 3 views
14

장고 관리자 변경 목록보기에 사용자 지정 인수를 전달하려고하므로 목록을 특수한 방식으로 필터링 할 수 있습니다. 'active_pp'라는 GET 매개 변수를 기반으로 start_date 및 end_date의 2 개 필드에서 쿼리 세트를 필터링하고 싶습니다. 올바르게 작동하려면 필터링을 받았지만 필터링 된 결과를 표시할지 아니면 일반적인 결과를 표시할지 여부를 지정하는 GET 쿼리 매개 변수를 전달할 수 없습니다.Django Admin 사용자 지정 변경 목록 인수 : 재정의 /? e = 1

보안 때문에 장고 관리자는 지정된 모델 필드와 관련이없는 쿼리 매개 변수를 필터링하여 필터링합니다. 잘못된 인수를 찾으면 관리자는 사용자를 현재보기로 리디렉션하지만 GET 쿼리 매개 변수를 e = 1로 바꿉니다. 내 사용자 지정 'active_pp'매개 변수를 허용 목록에 추가하여 페이지가 리디렉션되지 않고 매개 변수를 사용할 수있게하고 싶습니다.

다음은 queryset 사용자 정의가있는 admin.py의 ModelAdmin의 예입니다.

class FeaduredAdmin(admin.ModelAdmin): 

    .... 

    def get_changelist(self, request, **kwargs): 
     from django.contrib.admin.views.main import ChangeList 

     # Try to get the 'active_pp' query parameter 
     active_pp = request.GET.get('active_pp',None) 

     # Define a custom ChangeList class with a custom queryset 
     class ActiveChangeList(ChangeList): 
      def get_query_set(self, *args, **kwargs): 
       now = datetime.datetime.now() 
       qs = super(ActiveChangeList, self).get_query_set(*args, **kwargs) 
       return qs.filter((Q(start_date=None) | Q(start_date__lte=now)) 
          & (Q(end_date=None) | Q(end_date__gte=now))) 

     # use the custom ChangeList class if the parameter exists 
     if active_pp: 
      return ActiveChangeList 

     return ChangeList 

change_list에 전달 된 커스텀 GET querystring 인수를 허용하는 방법을 아는 사람이 있습니까? 읽기와 고려

감사합니다, 조

UPDATE : Uvasal의 제공 링크를 사용

, 나는 제대로 GET 매개 변수를 화이트리스트 수 있었다.

class ActiveFilterAminForm(forms.Form): 
    active_pp = forms.CharField() 

class FeaduredAdmin(admin.ModelAdmin): 

    .... 

    # Based on: http://djangosnippets.org/snippets/2322/ 
    advanced_search_form = ActiveFilterAminForm() 

    def get_changelist(self, request, **kwargs): 

     from django.contrib.admin.views.main import ChangeList 
     active_pp = self.other_search_fields.get('active_pp',None) 
     # now we have the active_pp parameter that was passed in and can use it. 

     class ActiveChangeList(ChangeList): 

      def get_query_set(self, *args, **kwargs): 
       now = datetime.datetime.now() 
       qs = super(ActiveChangeList, self).get_query_set(*args, **kwargs) 
       return qs.filter((Q(start_date=None) | Q(start_date__lte=now)) 
           & (Q(end_date=None) | Q(end_date__gte=now))) 

     if not active_pp is None: 
      return ActiveChangeList 

     return ChangeList 


    def lookup_allowed(self, lookup): 
     if lookup in self.advanced_search_form.fields.keys(): 
      return True 
     return super(MyModelAdmin, self).lookup_allowed(lookup) 


    def changelist_view(self, request, extra_context=None, **kwargs): 
     self.other_search_fields = {} 
     asf = self.advanced_search_form 
     extra_context = {'asf':asf} 

     request.GET._mutable=True 

     for key in asf.fields.keys(): 
      try: 
       temp = request.GET.pop(key) 
      except KeyError: 
       pass 
      else: 
       if temp!=['']: 
        self.other_search_fields[key] = temp 

     request.GET_mutable=False 
     return super(FeaduredProductAdmin, self)\ 
       .changelist_view(request, extra_context=extra_context) 
+0

이것은 적절한 DRY django를 지원하는 데 유용한 기능인 것 같습니다. – dashesy

답변

6

나는 그냥 Advanced Search 장고 발췌문에 설명 된대로 search_fields 클래스 변수에 사용자 정의 필터 필드를 넣어 필요가 있다고 생각합니다.

날짜 범위를 지원하도록 스 니펫을 수정할 수 있어야합니다.

+0

감사합니다. 당신이 제공 한 링크가 실제로 도움이되었습니다. 위에서 제공 한 것에 기반한 구현으로 위의 코드를 업데이트했습니다. - Joe –

3

요약하면, 여기에 위에서 사용 된 문서화되지 않은 해킹은 다음과 같습니다

사용중인 사용자 정의 GET 인수 (들)을 해제 한 후 request.GET._mutable = True, request.GET.pop()을 설정합니다.

+0

'request.GET.pop (key)'가 목록을 얻는다는 것을 주목하라. – WeizhongTu