2017-05-05 1 views
1

Ich versuche, eine Hierarchieansicht in Django zu erstellen, aber ich habe Schwierigkeiten, sinnvoll zu verstehen, wie QuerySets effektiv verwendet werden kann.Erstellen einer Hierarchieansicht in Django

Was denn ich bin mit dem Ziel ist schließlich eine HTML-Seite, die Kurse wie folgt angezeigt:

Main Course 1 --- Child Course 1 
       --- Child Course 2 

Main Course 2 --- Child Course 3 
       --- Child Course 4 

Jede Gruppe von Kursen in einem div gewickelt werden würde und Stil usw.

Aus meiner Sicht. py-Datei ich habe folgend:

class HierarchyView(generic.ListView): 
template_name = 'curriculum/hierarchy.html' 

def get_queryset(self): 
    return Offering.objects.all() 

def get_context_data(self, **kwargs): 
    context = super(HierarchyView, self).get_context_data(**kwargs) 
    context['main'] = self.get_queryset().filter(course_type='M') 
    context['sub'] = self.get_queryset().filter(parent_code__in=context['main']) 
    return context 

das Angebotsmodell ist so ausgelegt, dass parent_code ist ein selbstbezüglicher Fremdschlüssel (dh jeder Kurs kann ein Kind eines andere sein), wie t sein:

... 
parent_code = models.ForeignKey(
    'self', 
    null=True, 
    blank=True, 
    on_delete=models.SET_NULL) 
... 

Und in meinem HTML-Template Ich habe:

{% for mainoffering in main %} 
<div> 
<div>{{ mainoffering.course_name }}</div> 
    {% for offering in sub %} 
    <div>{{ offering.course_name }}</div> 
    {% endfor %} 
</div> 
{% endfor %} 

Was dies ergibt, ist jedoch, dass alle Kind-Kurse unter allen Hauptgerichten erscheinen, unabhängig davon, ob sie tatsächlich Kinder dieses Kurses, was offensichtlich nicht mein Ziel ist.

Ich lerne immer noch die Seile in Django, und ich habe Mühe, etwas zu finden, das in einfachem Englisch erklärt, was ich tun muss. Bitte helfen Sie!

+1

was Sie brauchen, ist Django-Mptt – e4c5

Antwort

0

Ich denke, dass Sie Ihre Vorlage ändern müssen, um jeden der untergeordneten Kurse an ihre übergeordneten Kurse anzupassen. Vielleicht so etwas wie:

{% for mainoffering in main %} 
<div> 
<div>{{ mainoffering.course_name }}</div> 
    {% for offering in sub %} 
    {% if offering.parent_code == mainoffering %} 
     <div>{{ offering.course_name }}</div> 
    {% endif %} 
    {% endfor %} 
</div> 
{% endfor %} 
0

Der Kontext [ ‚sub‘] werden alle von ihnen ohne jede Gruppierung zurückkehren, Bestellung etc. Sie einige Dinge tun können, um das gewünschte Verhalten zu bekommen.

Sie können einen Prefetch-Bezug herstellen.

from django.db.models import Prefetch 

offerings = Offering.objects.filter(course_type='M').prefetch_related(
    Prefetch(
     "courses_subset", 
     queryset=Offering.objects.filter(parent_code__in=offerings), 
     to_attr="sub" 
    ) 
) 
for o in offerings:   
    print o.sub 

Sie können dies tatsächlich zu einer Methode in Ihrem Modell machen und ein Template-Tag erstellen (ich würde das höchstwahrscheinlich verwenden).

method in your Offering model

def get_child_courses(self): 
    child_courses = Offerings.objects.filter(parent_code=self.id) 
    return child_courses 

template tag

@register.simple_tag 
def get_child_courses(course): 
    return course.get_child_courses() 

in Ihrer Vorlage:

{% for mainoffering in main %} 
<div> 
<div>{{ mainoffering.course_name }}</div> 
    {% for offering in mainoffering|get_child_course %} 
    <div>{{ offering.course_name }}</div> 
    {% endfor %} 
</div> 
{% endfor %} 

Sie gruppieren können sie in der Vorlage, wie durch accraze vorgeschlagen. Ich würde persönlich für die zweite Option gehen

+0

Vielen Dank für die Zeit nehmen, um so gut zu erklären, kann ich am Ende mit Ihrer Methode, aber accraze Lösung den Nagel auf den Kopf treffen! – Luke

Verwandte Themen