2014-12-04 4 views
3

내 앱의 모든 URL에 대한 동적 URL 접두어가 있어야합니다.Django 동적 접두사가있는 URL

저는 url(r'^myprefix/app', include('app.urls'))과 같이 정적 접두사를 사용하는 것에 익숙합니다.

대신 myprefix이 동적이어야합니다 (예 : url(r'^(?P<prefix>\w+)/app', include('app.urls'))).

그게 효과가 있지만 여기 키커가 있습니다. 모든 뷰에 대한 키워드 인수로 prefix을 보내지 않기를 바란다. 나는 그것을 잡아서 미들웨어 같은 곳에서 사용할 수 있기를 원합니다.


다양한 용도로 사용할 수 있도록 다양한 테스트 랩을 관리하는 소프트웨어 (이 장고 프로젝트)가 있습니다. 앱에서 어떤 실험실이 작동하는지 파악해야합니다.

현재 나는 다음과 같이이 일을 해요 :

class LabMiddleware(object): 
    def process_request(self, request): 
     request.current_lab = 'lab1' # Note that this is currently hard coded 

요구 사항은 lab_name이 다음 내 LabMiddleware에 익숙해 질 것입니다 경우 사용자는 http://host/<lab_name>/app 같은 URL에 갈 수 있다고 주장한다. 이 때문에 나는 분명히 내 생각에 매번 lab_name을 받아 들일 필요가 없기 때문에 성가시다.


는 UPDATE : Sohan는 그의 대답에 준 것에

빌딩, 나는 사용자 정의 미들웨어 클래스를 사용하여 종료 :

urls.py를

url(r'^(?P<lab_name>\w+)/', include('apps.urls')), 

apps/urls.py

url(r'^app1/', include('apps.app1.urls', namespace='app1')), 

middleware.py

class LabMiddleware(object): 
    def process_view(self, request, view_func, view_args, view_kwargs): 
     lab_name = view_kwargs.get('lab_name') 
     if lab_name: 
      request.current_lab = Lab.objects.get(name=lab_name) 
      # Remove the lab name from the kwargs before calling the view 
      view_kwargs.pop('lab_name') 
      return view_func(request, *view_args, **view_kwargs) 

settings.py

MIDDLEWARE_CLASSES = (
    # Default Django middleware classes here... 
    'raamp.middleware.LabMiddleware', 
) 

이 URL에 실험실 이름이하고 요청에 추가 저를 허용했다. 그런 다음 view_kwargs에서 제거하면 뷰 기능으로 전달되지 않고 의도 한대로 모든 것이 작동합니다.

위 코드는 가장 최적화 된 코드가 아닙니다 (예 : 모든 요청에 ​​대해 데이터베이스를 쿼리하고 있음). 이 문제를 해결하는 방법을 보여주는 것이 중요하지 않기 때문에 이것을 캐싱해야하는 코드는 제거했지만, 프로덕션 시스템에서이 코드를 사용하는 경우이 코드를 개선해야한다는 점을 언급 할 가치가 있습니다.

+0

url(r'^(?P<lab_name>\w+)/app'이 IMO보기의 모든 기능에 또 다른 인수를 받아들이는 같은 경로 모양을 과잉 만 최소한 복잡하지 않습니다. 뷰 애트리뷰트가 routes.py의 구조와 직접적으로 일치하면 앱을 유지하고 이해하는 것이 더 쉬울 것이라고 생각합니다. –

+0

모든 단일 뷰 함수에 대해 'lab_name'매개 변수를 포함해야 할 필요가 있다는 것이 문제였습니다. 그 정보로 무엇인가를하기 위해 모든 사람에게 부름을 받는다. 대용량 응용 프로그램의 경우 (현재는) 여러 사용자에게 특히 번거롭고 오류가 발생하기 쉽습니다. 결국, 내가 다른 방식으로 작동시키지 못한다면, 이것은 내가 취할 구현이 될 것이지만 나는 그것을 피하려고 노력하고있다. – Jared

+0

아하, 실제로 좋은 해결책은 데코레이터를 대신 사용하는 것입니다. 데코레이터는'lab_name' 인수를 처리하고 "삼킬"수 있습니다. 예를 들어 보겠습니다. –

답변

2

각보기 기능을 래핑하는 데코레이터를 만들 수 있습니다. 데코레이터는 실명 매개 변수에 대한 처리 작업을 처리 할 수 ​​있으며 모든 뷰는 lab_name 매개 변수를 볼 필요가 없습니다.

def process_lab_name(request, lab_name): 
    request.current_lab = lab_name 

def lab(view_func): 
    def _decorator(request, lab_name, *args, **kwargs): 
     # process the lab_name argument 
     process_lab_name(request, lab_name) 
     # when calling the view function, exclude the lab_name argument 
     response = view_func(request, *args, **kwargs) 
     return response 
    return wraps(view_func)(_decorator) 

@lab 
def some_view(request): 
    return render(...) 

그리고

+0

감사합니다. 실제로는 비슷한 방향으로 나를 안내하지만 대신 여기에 표시된 내용을 효과적으로 수행하기 위해 process_view()를 정의하는 미들웨어 클래스를 사용합니다. 그런 다음 뷰 함수를 호출하기 전에'kwargs'에서'lab_name '을 제거합니다. 나중에 특정 솔루션을 사용하여 게시물을 업데이트 하겠지만, 문제를 해결하기 때문에 답변을 승인으로 표시하고 있습니다. 감사! – Jared