장고 템플릿과 지역 트릭
django 책은 컨텍스트 사전으로 긴 매개 변수 목록을 입력하지 않도록 로컬 트릭을 제공합니다.
http://www.djangobook.com/en/2.0/chapter04/
예:
def current_datetime(request):
dt_now = datetime.datetime.now()
return render_to_response('current.html', {'dt_now': dt_now})
된다 :
def current_datetime(request):
dt_now = datetime.datetime.now()
return render_to_response('current.html', locals())
게으른 프로그래머에게 이것을 권장하지만 성능에 영향을 미칠 수있는 오버 헤드를 지적합니다.
여러분 중 일부가 실제 응용 프로그램에서 로컬 트릭을 사용하고 있는지 알고 싶습니다. 당신은 그것을 추천합니까 아니면 나쁜 습관입니까?
나는 반복을 좋아하지 않습니다. "DRY", "Do n't Repeat Yourself"가 핵심 프로그래밍 원리라고 생각합니다. 결과적으로 나는 실제로 locals()
비슷한 상황에서 사용 했습니다. Django 템플릿 렌더링은 이런 종류의 유일한 상황과는 거리가 멀습니다. 일반적인 경우는 "dict를 받아들이지 만 dict에 추가 항목이 포함되어 있는지 상관하지 않는 함수 또는 연산자"입니다. (예를 들어, Python의 일반적인 문자열 형식은 또 다른 경우입니다.)
그러나 상쇄 원칙이 있습니다. 프로그램은 가능한 한 현지화 된 방식으로 이해할 수 있어야합니다. 이는 유지 관리 및 리팩토링에 도움이됩니다 (어떤 리팩토링이 허용되는지 확인하기 위해 다른 파일을 연구 할 필요가 없기 때문입니다). 이는 locals()
경우에 따라 템플릿 (또는 문자열 형식 등)이 로컬 리터럴 (변수가 거의 사용 locals()
되지 않고 따라서 큰 승리가 아닌 드문 경우입니다 !-)이면 괜찮지 만 문제가 있음을 나타냅니다. 템플릿이 다른 파일에있는 일반적인 경우입니다.
따라서 locals()
대부분의 경우를 사용 하면 리팩토링이 심각하게 방해됩니다. 파이썬의 거의 모든 상황에서, 지역 변수와 그 이름은 "외부 적으로 보이는"효과가 없기 때문에 지역 리팩토링의 일부로 자유롭게 변경할 수 있습니다 ...하지만 locals()
중단을 사용 하면 갑자기 변수 이름을 안전하게 바꿀 수 없습니다. 더 나은 명확성을 제공하는 다른 이름으로, 이전 이름이 필요하지 않은지 확인하기 위해 별도의 템플릿 파일을 연구 할 때마다 (그리고 아마도 편집 할 수있는) 변수 등의 필요성을 제거하는 방식으로 코드 흐름을 리팩토링합니다. 예를 들어 i18n / L10n 목적을 위해 여러 가지 다른 자연 언어로 유지 관리되는 경우 중요하지 않을 수있는 템플릿 파일).
결과적으로 성능의 이차적 인 문제 외에도 장기적인 유지 보수가 필요하므로 리팩토링과 지역성이 용이 한 코드 인 "심각한" "프로덕션"코드에서 사용 하는 것에 대한 강력한 압력이 locals()
있습니다. 그래서 내가 "모퉁이를 자르는 것"보다는 "내가 아는 최선의 방법으로 프로그래밍"할 때 나는 피하는 것이 더 낫다는 것을 알고있다 locals()
.
템플릿이 렌더링되는 컨텍스트에서 원하는 값은 결국 로컬 베어 이름으로 "자연스럽게"사용할 수있는 것은 아닙니다. 아마도 그들 중 일부 또는 다수는 계산의 결과, 목록 또는 사전의 항목 등일 수 있습니다. 이 경우 locals()
로컬 베어 이름을 지정하는 대신 적절한 사전에 해당 값을 축적하면 "모퉁이를 잘라"하려는 유혹을 피하는 것이 더 쉽습니다.
두 가지 좋은 원칙 (반복을 피하고 좋은 지역성을 가짐)이 필연적으로 충돌하기 때문에 가장 쉬운 절충안은 아닙니다. 따라서 좋은 질문입니다! 그리고 날카로운 흑백 답변에 완전히 취약한 사람은 아니기 때문에 양쪽으로 확장하려고 노력했습니다. 결국, 프로그래밍 팀이 팀 유니폼 스타일 가이드 라인을 채택하고이를 고수하도록 권장하는 "스타일"측면 중 하나라고 생각합니다. 적어도 매번 반복해서 결정을 내릴 필요가 없어집니다. 문제가 발생하면보다 동질적인 (따라서 유지 관리 가능한) 코드 기반이 생성됩니다. [[많은 다른 사람들이 그래도 내가 참여한 팀의 스타일 가이드 라인에서이 특정 요점을 명시 적으로 언급 한 적이 없다는 것을 고백해야합니다!-)]]
나는 종종 다음을하려고 생각했지만 그것이 정말로 도움이되는지 확실하지 않습니다.
class MyStruct(object):
pass
def my_view(request, id):
c = MyStruct()
c.customer = ..
c.invoice = ..
c.date = ..
return render_to_response('xxx,html',c.__dict__)
개인적으로 좋아하지 않습니다. 내가 선호하는 이유는 아마도 "명시적인 것이 암묵적인 것보다 낫다"라는 오래된 파이썬 용어 외에는 없을 것입니다. 내 템플릿에 무엇이 들어가는 지 정확히 알고 싶습니다.
나는 아무 문제없이 사용했습니다 (지금까지!).
나는 특히 타이핑을 좋아하지 않기 때문에 그것을 좋아합니다. 같은 코드
'customer' : customer,
'invoice' : invoice,
'date' : date
나에게는 우스꽝스러워 보이며 피할 수 있다면 그렇게 할 것입니다. 내가 파이썬을 좋아하는 이유 중 하나는 상용구가 없다는 것입니다 (실제로 상용구는 아니지만 비슷합니다).
함수에서 정의하는 지역 변수의 수에 따라 다릅니다.
템플릿에 반환하려는 숫자와 정확히 일치하거나 '추가'변수가 정수 또는 부울과 같은 간단한 구조 인 경우 더 많은 작업이 필요하기 때문에 명시 적으로 반환 할 필요가 없다고 생각합니다.
그러나 반면에 뷰에 템플릿으로 보낼 데이터를 생성하기 위해 뷰에서 사용하는 모델의 인스턴스와 같이 복잡한 '도우미'변수가 많은 경우 명시 적 사용을 고려할 수 있습니다. 템플릿으로 반환 할 변수.
나는 이것이 오래된 스레드라는 것을 알고 있습니다 ... 현재 render_to_response는 더 이상 사용되지 않습니다. 대신 locals ()없이 render를 사용하십시오. 모든 현지인을 지나치는 것은 나쁜 습관입니다. 다음은 views.py 예제입니다.
from django.shortcuts import render
from django.contrib.auth.decorators import login_required
@login_required
def mybooks(request):
entries = Book.objects.all()
return render(request, 'mybooks.html', {'entries': entries})
views.py
명확하게 유지하면서 혼란을 줄이려면 : In controllers.py
:
import sys
def auto_context(the_locals=None):
# Take any variable in the locals() whose name ends with an underscore, and
# put it in a dictionary with the underscore removed.
if the_locals is None:
# We can access the locals of the caller function even if they
# aren't passed in.
caller = sys._getframe(1)
the_locals = caller.f_locals
return dict([
(key[:-1], value)
for (key, value) in the_locals.items()
if key[-1] == "_"])
에서 views.py
:
from app.controllers import auto_context
def a_view(request):
hello_ = "World" # This will go into the context.
goodnight = "Moon" # This won't.
return render(request, "template.html", auto_context())
에서 template.html
사용 {{ hello }}
.
You're unlikely to give a variable a name ending in an underscore accidentally. So you'll know exactly what's going into the template. Use auto_context()
or equivalently auto_context(locals())
. Enjoy!
I agree with Alex. Don't see the point of creating a class instance (as niels suggested) when you can just do this:
def my_view(request, id):
customer = ..
invoice = ..
date = ..
return render_to_response('xxx,html', locals())
If you want a performance reason, dotted lookups are slower.
If you want a maintenance reason, this is fewer lines of code, even more readable, and one fewer unnecessary structures.
ReferenceURL : https://stackoverflow.com/questions/1901525/django-template-and-the-locals-trick
'programing' 카테고리의 다른 글
알파 블렌딩 양을 지정하여 RGB 색상을 계산하는 방법은 무엇입니까? (0) | 2021.01.17 |
---|---|
KCacheGrind에서 cProfile 결과 사용 (0) | 2021.01.17 |
프로젝트 별 (또는 파일별로) Xcode에서 들여 쓰기 설정을 지정할 수 있습니까? (0) | 2021.01.17 |
임의의 가비지 바이트를 파일에 쓰는 명령이 있습니까? (0) | 2021.01.17 |
IEnumerable에 단일 항목을 추가하는 Linq 메서드가 있습니까? (0) | 2021.01.17 |