[python] 장고 템플릿에서 쿼리 필터링을 수행하는 방법

뷰 내에서 파이썬 코드에 해당하는 객체 세트를 얻으려면 django 템플릿 내에서 필터링 된 쿼리를 수행해야합니다.

queryset = Modelclass.objects.filter(somekey=foo)

내 템플릿에서 내가하고 싶습니다

{% for object in data.somekey_set.FILTER %}

하지만 FILTER를 작성하는 방법을 찾을 수없는 것 같습니다.



답변

당신은 이것을 할 수 없습니다. Django 프레임 워크 작성자는 데이터 논리에서 프레젠테이션 코드를 엄격하게 분리하려고했습니다. 필터링 모델은 데이터 로직이고 HTML 출력은 프리젠 테이션 로직입니다.

따라서 몇 가지 옵션이 있습니다. 가장 쉬운 방법은 필터링을 수행 한 다음 결과를에 전달하는 것 render_to_response입니다. 또는라고 말할 수 있도록 모델에 메소드를 작성할 수 있습니다 {% for object in data.filtered_set %}. 마지막으로, 고유 한 템플릿 태그를 작성할 수 있지만,이 특정 경우에는 이에 대해 권장하지 않습니다.


답변

다음과 같이 추가 템플릿 태그를 추가합니다.

@register.filter
def in_category(things, category):
    return things.filter(category=category)

그런 다음 할 수 있습니다.

{% for category in categories %}
  {% for thing in things|in_category:category %}
    {{ thing }}
  {% endfor %}
{% endfor %}


답변

정기적으로이 문제가 발생하고 “방법 추가”솔루션을 자주 사용합니다. 그러나 “메서드 추가”또는 “뷰에서 계산”이 작동하지 않거나 제대로 작동하지 않는 경우가 있습니다. 예를 들어 템플릿 조각을 캐싱하고 그것을 생성하기 위해 사소하지 않은 DB 계산이 필요할 때. 필요한 경우가 아니면 DB 작업을 수행하고 싶지 않지만 템플릿 논리에 깊이 들어가기 전까지는 필요한지 알 수 없습니다.

다른 가능한 솔루션 :

  1. http://www.djangosnippets.org/snippets/9/에 있는 {% expr <expression> as <var_name> %} 템플릿 태그를 사용합니다 . 표현식은 템플릿의 컨텍스트를 로컬 범위로 사용하는 합법적 인 Python 표현식입니다.

  2. 템플릿 프로세서를 변경하십시오. Jinja2 ( http://jinja.pocoo.org/2/ )에는 Django 템플릿 언어와 거의 동일한 구문이 있지만 완전한 Python 기능을 사용할 수 있습니다. 또한 더 빠릅니다. 이 도매를 할 수있는, 또는 당신은 템플릿의 사용을 제한 할 수 당신이 작업하고, 그러나 디자이너 유지 페이지에 대한 장고의 “안전”템플릿을 사용합니다.


답변

다른 옵션은 항상 적용하려는 필터가있는 경우 반환 된 결과에 항상 필터를 적용 하는 사용자 지정 관리자 를 해당 모델에 추가하는 것 입니다.

이것의 좋은 예는 것입니다 Event당신이 뭔가를 원하는하고자하는 모델을 할 쿼리의 90 %를 모델 Event.objects.filter(date__gte=now)당신을 즉, 일반적으로 관심 Events이 곧입니다. 이것은 다음과 같습니다.

class EventManager(models.Manager):
    def get_query_set(self):
        now = datetime.now()
        return super(EventManager,self).get_query_set().filter(date__gte=now)

그리고 모델에서 :

class Event(models.Model):
    ...
    objects = EventManager()

그러나 이것은 Event모델에서 수행되는 모든 기본 쿼리에 대해 동일한 필터를 적용 하므로 위에서 설명한 기술 중 일부는 유연하지 않습니다.


답변

이것은 할당 태그로 해결할 수 있습니다.

from django import template

register = template.Library()

@register.assignment_tag
def query(qs, **kwargs):
    """ template tag which allows queryset filtering. Usage:
          {% query books author=author as mybooks %}
          {% for book in mybooks %}
            ...
          {% endfor %}
    """
    return qs.filter(**kwargs)


답변

2020 년에 답을 찾고있는 모든 사람에게. 이것은 저에게 효과적이었습니다.

보기에서 :

 class InstancesView(generic.ListView):
        model = AlarmInstance
        context_object_name = 'settings_context'
        queryset = Group.objects.all()
        template_name = 'insta_list.html'

        @register.filter
        def filter_unknown(self, aVal):
            result = aVal.filter(is_known=False)
            return result

        @register.filter
        def filter_known(self, aVal):
            result = aVal.filter(is_known=True)
            return result

템플릿에서 :

{% for instance in alarm.qar_alarm_instances|filter_unknown:alarm.qar_alarm_instances %}

의사 코드에서 :

For each in model.child_object|view_filter:filter_arg

도움이되기를 바랍니다.


답변