2011-02-06 4 views
0

여러 장르의 정보 테이블을 표시하기 위해 장고를 사용하려고하는데,이를위한 모범 사례가 무엇인지 모릅니다. 여기 내 models.py의 버전을 박탈이다 :Django의 특정 관련 객체에서 데이터 쿼리하기 템플릿

from django.contrib.auth.models import User 

class Widget(models.Model): 
    name = models.CharField(max_length=50) 
    pass 

class Finished_Widget(models.Model): 
    user = models.ForeignKey(User) 
    thing = models.ForeignKey(Thing) 
    created = models.DateTimeField(editable=False) 

그것은 사용자와 위젯이 Finished_Widget 오브젝트의 알 수없는 전화 번호를 통해 연결되어있는 아주 간단한 설치합니다. 내 html에 표시하고 싶은 것은 위젯 이름의 인스턴스 목록과 가장 최근에 완성 된 위젯의 날짜입니다. 분명히 아래 코드는 작동하지 않지만 잘하면 출력 할 데이터를 보여줍니다.

{% for widget in widget_list %} 
<p>{{ widget.name }}</p> 
<p>{{ widget__Finished_Widget.latest.created }}</p> 
{% endfor %} 

I 포함한 문제에 대한 다른 접근 방법에 대해 생각했습니다

  • 뷰에서 사전을 만들어보기
  • 를 통해 추가 속성으로 원하는 날짜를 추가하고 템플릿에서 호출하는 것
  • 'through'인수를 사용하는 ManyToManyField
  • 최신 Finished_Widget의 생성 날짜를 호출하는 위젯에 메타를 추가하는 것

불행히도 이러한 작업을 수행하지 못했고 올바른 경로에 있는지도 모릅니다.

참고 : 저는이 문제에 대해 꽤 많은 변형을 이미 발견했기 때문에이 사실을 속임수에 매우 가깝게 만듭니다.하지만 Finished_Widget 목록을 좁히고 싶지 않아서 도움이되지 않는 것 같습니다. 위젯 ID와 일치하는 사용자 ID와 일치하는 사용자에게 만 최신 사용자로 변경합니다.

답변

2

업데이트 대답 : 당신이 사용자의 목록이 있다면, 예를 들어, USER_LIST라고,이 같은 각 사용자와 그/그녀의 최신 위젯을 표시 할 수 있습니다.

가장 쉬운 방법은 문제를 해결하는 것입니다.하지만 문제가 있습니다.

for widget in widget_list: 
    widget.latest_finished_widget = widget.finished_widget_set.filter(user=request.user).latest('created') 

{% for widget in widget_list %} 
    <p>{{ widget.name }}</p> 
    <p>{{ widget.latest_finished_widget }}</p> 
{% endfor %} 

이 코드는 쓰기 쉽지만 모든 반복마다 db 쿼리를 실행해야합니다.

하나의 빠른 솔루션을 쿼리 분할이라고합니다. 2 개의 쿼리와 파이썬을 사용하여 SQL을 사용하지 않고 가능한 한 효율적으로 역방향 관계를 채 웁니다.

widgets = Widget.objects.filter(...) 

finished_widget_map = dict( 
    [(x['thing__id'], x['created']) for x in 
     Finished_Widget.objects.filter(thing__in=widgets, user=request.user).values_list('thing__id', 'created').order_by('created')]) 
    # this ensures we only select what we need, thing__id and the created column 
    # ordering by created will ensure only the last (latest) will appear in our dictionary 

for widget in widgets: 
    widget.latest_finished_widget_created = finished_widget_map.get(widget.id, 'No Widget') 


{% for widget in widgets %} 
    {{ widget.name }} 
    {{ widget.latest_finished_widget_created }} 
{% endfor %} 

항상 상충 관계가 있습니다. Finished_Widgets가 많이있는 경우에는 잠재적으로 느려질 수 있습니다. python은 무의미하게 dict을 채우려 고 시도합니다.

+0

Yuji, 나는 당신이 우연히 왜 내가 이것에 대해 많은 어려움을 겪고 있는지 강조했을 것입니다. 어디에서 'finished_widget_set'을 얻을 수 있는지 설명해 주시겠습니까? 그것은 설명서를 찾을 수없는 장고 템플릿 구문의 일부 측면처럼 보입니다? 아니면 내가 다른 곳에서 정의 할 것이라고 가정하고 있습니까? – IanWhalen

+1

@IanWhalen, 대단한 질문입니다! 예, django는 관계를 "거꾸로"검색하기위한 편리한 메소드를 자동으로 생성합니다. http://docs.djangoproject.com/en/dev/topics/db/queries/#following-relationships-backward - 기본적으로 : fieldname_set. 하지만 위젯 당 쿼리 1 개를 생각할 때 비효율적입니다. 하나의 오브젝트가 있고 100 개의 관련 오브젝트를 모두 원할 때 더 유용합니다. –

+0

추신 : 템플릿 도트 표기법은 엄격히 파이썬 기반이며 점 표기법을 제외하고는 특별한 템플릿 구문이 없습니다. http://docs.djangoproject.com/en/dev/ref/templates/api/#render 그것은 python을 사용합니다. dict 조회, attr 조회, 색인 조회, 자동으로 실패합니다. 그래서 당신이 인식하지 못하는 점 표기법이 있다면 그것은 파이썬 딕트 키, attr 또는 인덱스입니다! –

0

글쎄, 내 질문에 완전히 대답하기에 충분한 정보가 없다고 생각하지만 가장 최근의 Finished_Widget만을 반환하는 간단한 해결책은 "latest_widget"이라는 메서드를 User 모델에 추가하는 것입니다 :

class User(models.Model): 
    #... 
    def latest_widget(self): 
     return self.widgets.all().order_by('-created')[0] 

엄밀히 말하자면 기술적으로 Finished_Widget 모델에 추가 할 수 있습니다. Django의 auth 모듈에서 User 모델을 사용하고 있다면이 기능을 추가하기 위해 모델을 서브 클래스 화하기를 원할 것입니다.

일단이 방법을 사용하면 템플릿에서 호출하면됩니다. user 객체를 전달을 위해 필요에 따라

{% for uu in user_list %} 
<p> 
    {{uu.username}}: {{uu.latest_widget.name}} 
</p> 
{% endfor %} 
+0

미안하지만 충분히 명확하지 않은 경우 Walter가 있지만 사용자가 아닌 위젯 목록을 반복 할 예정이며 최신 Finished_Widget 객체에서 'created'필드에 액세스하려고합니다. 최신 위젯 개체. – IanWhalen

+0

그는 아마도'위젯 (widget)'인스턴스 인'widget_list'를 반복하고있는 것으로 보입니다. 그래서 거기에 들어가야 할 것입니다. 상관없이 아이디어가 작동합니다 :) 편집 : 브라우저 새로 고침이 실패합니다. –

+0

아, 그래, 이제 알겠습니다. 글쎄, 나를 위해 솔루션을 공식화하는 데 가장 도움이되는 것은 샘플 데이터 (모델 및 DB에 저장 됨)와 페이지에 표시되는 방법을 보는 것입니다. – Walter

관련 문제