2016-09-29 4 views
0

나는 상용어가 정말 싫다. 그러나 다음 코드가 큰 이점이라는 것을 부정 할 수는 없습니다. 그래서 제 질문은 파이썬에서 매크로 (템플릿) 프리 프로세서가 없다는 사실을 보완하기 위해 파이썬에서 무엇을합니까?Django 클래스 기반 뷰 보일러 플레이트를 줄이는 방법

하나의 아이디어는 공장 기능을 작성하는 것이지만 어디서부터 시작해야할지 모르겠다는 것을 기꺼이 인정할 것입니다. (이것은 선언 클래스와 흥미로운 "매직"메타 클래스 항목이있는 장고입니다. 깨닫기에 충분하고, 깨지면 이해하거나 디버깅하기에 충분하지 않습니다.)

다른 하나는 이것을 템플릿에 넣고 Bash에서 ${var:-default} 같은 것을 구현하는 간단한 프리 프로세서를 통해 가져옵니다. ,

with my_preprocessor("somefile.py") as f: 
    code = compile(f.read(), "somefile.py", 'exec') 
    exec(code) # in the current namespace 

을 (What is an alternative to execfile in Python 3? 참조)하지만 지난 몇 년 동안 본 적이 exec에 대한 경고 많이 있습니다. 인용 된 SO 응답은 디버깅을위한 줄 번호를 문제로 언급합니다. 다음은 메모리 누수를 포함한 미묘한 문제에 대한 경고 인 http://lucumr.pocoo.org/2011/2/1/exec-in-python/입니다. 나는 그들이 결코 삭제되지 않는 클래스를 정의하는 코드에 적용되지 않을 것이라고 생각하지만, 다른 한편으로는 난해한 문제를 프로덕션 환경에 적용 할 수있는 가장 작은 위험을 원하지 않습니다.

의견이나 안내를 환영합니다. 가장 좋은 방법은 상용구 잘라 내기 및 붙여 넣기를 허용하는 것입니까? 그러한 템플리트의 붙여 넣기 수정은 일반적으로 열 개 미만인 20 개가 넘지 않습니다.

예제 코드. #V로 표시된 줄만 일반적으로 사용자 지정할 수 있습니다. 처음 두 클래스는 한 번만 사용되며 세 번째 클래스는 한 번만 사용됩니다.

#--- this is boilerplate for a select-view ---- 
#--- just replace the string "User" by the relevant model and customize 

class UserSelectPopupTable(tables.Table): 

    id = SelectorColumn(clickme='<span class="glyphicon glyphicon-unchecked"></span>') #V 

    class Meta: 
     model=User 
     attrs={ 'class':'paleblue' } 
     empty_text='Sorry, that search did not match anything.' 
     fields=('name','address',)  #V 
     sequence=('id','name','address',) #V 

class UserFilter2(django_filters.FilterSet): 
    name = django_filters.CharFilter(lookup_expr='icontains')  #V 
    address = django_filters.CharFilter(lookup_expr='icontains') #V 
    class Meta: 
     model = User 
     fields = ('name','address',) #V (usually same as previous) 

class UserSelectPopup(FilterTableView): 
    model=User 
    table_class=UserSelectPopupTable 
    filterset_class=UserFilter2 
    template_name='redacted/select_in_popup.html' 

#--- end boilerplate 
+0

생성 된 클래스를 어떻게 사용하는지 예를 들려 줄 수 있습니까? –

+0

보기 :'url (r '^ UserSelectPopup/$', views.UserSelectPopup.ashview(), name = 'userselectpopup'), ' – nigel222

+0

공장 쓰기는 생각보다 쉽습니다. 나는'type' 3-arg doc을 읽고 다시 읽은 다음, 좀 더 테스트하고 정리 한 후에 자신의 질문에 대답 할 것입니다. – nigel222

답변

2

파이썬과 장고는 굉장합니다.

클래스 (https://docs.python.org/3/library/functions.html#type)를 동적으로 생성하는 데 사용하는 type의 3 인수 양식에 대한 (매우 짧은) 문서를 읽고 다시 읽습니다. 나는 보조 전화 보조자 Classfactory을 작성하여 type에 대한 더 나은 인터페이스를 제공하고 클래스 구조를 대부분 잘라 붙이기가 된 함수 호출로 번역했습니다! 나는 지금 내가 갑자기이 될 수 단지 장고 Meta 클래스 아니다 것을 깨달았다 다음 (이었다 강한 나는 또한 생각 파이썬에서 자바 스크립트를 작성할 수 있음을 증명하는 ... 본능이 삽입 세미콜론)

def Classfactory(classname, inheritsfrom=(object,), **kwargs): 
    inh = inheritsfrom if isinstance(inheritsfrom, tuple) else (inheritsfrom,) 
    return type(classname, inh, kwargs) 

ThisPopupFilter = Classfactory('ThisPopupFilter', django_filters.FilterSet, 

    name = django_filters.CharFilter(lookup_expr='icontains') , 
    address = django_filters.CharFilter(lookup_expr='icontains') , 
    Meta = Classfactory('Meta', 
     model = User, 
     fields = ('name','address',), 
    ), 
) 
ThisPopupTable = Classfactory('ThisPopupTable', tables.Table, 

    id = SelectorColumn(clickme='<span class="glyphicon glyphicon-unchecked"></span>'), 

    Meta = Classfactory('Meta', # default inherit from object 
     model=User, 
     attrs={ 'class':'paleblue' }, 
     empty_text='Sorry, that search did not match anything.', 
     fields=('name','address',) , 
     sequence=('id','name','address',) , 
    ), 
) 

UserSelectPopup = Classfactory('UserSelectPopup', FilterTableView, 
    model=User, 
    table_class=ThisPopupTable, 
    filterset_class=ThisPopupFilter, 
    template_name='silson/select_in_popup.html', # this template handles any such view 
) 

에 도착 다른 클래스 내부에서 정의됩니다. 다른 곳에서 필요하지 않은 클래스는 필요한 곳에서 중첩 될 수 있습니다. 그래서

def SelectPopupFactory(Model, fields, sequence=None, 
       clickme='<span class="glyphicon glyphicon-unchecked"></span>' , 
       empty_text='Sorry, that search did not match anything.',): 
    return Classfactory('UserSelectPopup', FilterTableView, 

    model=Model, 
    template_name='silson/select_in_popup.html', # this template handles any such view 

    table_class=Classfactory('ThisPopupTable', tables.Table, 
     id = SelectorColumn(clickme=clickme), 
     Meta = Classfactory('Meta', # default inherit from object 
      model=Model, 
      attrs={ 'class':'paleblue' }, 
      empty_text=empty_text, 
      fields=fields, 
      sequence=sequence, 
    )), 
    filterset_class=Classfactory('ThisPopupFilter', django_filters.FilterSet, 
     name = django_filters.CharFilter(lookup_expr='icontains') , 
     address = django_filters.CharFilter(lookup_expr='icontains') , 
     Meta = Classfactory('Meta', 
      model = Model, 
      fields = ('name','address',), 
    )), 
) 

UserSelectPopup = SelectPopupFactory(User, 
    fields=('name','address',), 
    sequence=('id','name','address',) , 
    ) 

는 사람이 근본적으로 잘못 아무것도 볼 수 ... 내가 인수 공장 기능으로 이동 할 수 있었다 재 배열 더 비트와 함께 다음 세 번째 안에 처음 두 클래스를 이동하고? (나는 약간 놀랐다. 처음 시도했을 때, 모멘트 오타가 발생하지 않았다.)

UPDATE workday later : 나는 이것이 예제/개념 증명으로 OK라고 생각한다. 충돌하지 않고) 실제 django_filters 및 django_tables2 사용법과 관련하여 여기에없는 몇 가지 중요한 사항이 있습니다. 내 factory 함수는 진화하여 더 많은 기능을 제공하지만 factory-class가 아닌 원래의 클래스 정의와의 관련성은 낮습니다.

관련 문제