Django und Modelle mit mehreren Fremdschlüssel
Ich bin neu in Django und ich war sehr beeindruckt, so weit von seinen Fähigkeiten. Ich Spiele mit komplexeren Modellen und ich bin ein problem, Sie richtig zu verwenden. Mit Django 1.3, ich versuche eine Inhaltsangabe zu schreiben-Seite, die hätte die drei Modelle unten mit der folgenden Struktur. In anderen Worten, eine Liste der Fahrten mit Ihren Zielen und Aktivitäten.
- Reise 1
- Ziel 1
- Ziel 2
- Aktivität 1
- Reise 2
- Ziel 1
- Aktivität 2
Modelle
- Reise <-> TripDestination <-> Ziel (eine Reise kann mehrere Ziele)
- Aktivität -> Reise -, Aktivitäts -> Ziel (eine Aktivität definiert ist, für eine Reise zu einem bestimmten Ort/destination)
class Destination(models.Model):
city_name=models.CharField()
class Trip(models.Model):
departing_on=models.DateField()
returning_on=models.DateField()
destinations=models.ManyToManyField(Destination)
class Activity(models.Model):
destination=models.ForeignKey(Destination, null=False)
trip=models.ForeignKey(Trip, null=False)
Ich bin versucht zu schreiben, eine Ansicht, die würde erzeugen Sie eine Seite mit der Struktur, die oben präsentiert. Das Hauptproblem, das ich habe jetzt ist die Darstellung der Aktivitäten für eine bestimmte Reise und Ziel. Wie Sie sehen können, in dem code unten, Baue ich ein Wörterbuch und ich bezweifle, es ist die richtige Sache zu tun. Darüber hinaus wird die Ansicht
Ansicht
def list_trip(request, template_name = 'trip-list.html'):
trips = Trip.objects.all()
# Build a dictionary for activities -- Is this the right thing to do?
activities = Activity.objects.filter(trip__in=trips)
activities_by_trips = dict()
for activity in activities:
if activity.trip_id not in activities_by_trips:
activities_by_trips[activity.trip_id] = dict()
if activity.destination_id not in activities_by_trips[activity.trip_id]:
activities_by_trips[activity.trip_id][activity.destination_id] = []
activities_by_trips[activity.trip_id][activity.destination_id].append(activity)
return render_to_response(template_name, {
'page_title': 'List of trips',
'trips': trips,
'activities_by_trips': activities_by_trips,
})
Vorlage
{% block content %}
{% for trip in trips %}
{{ trip.id }} - {{ trip.name }}
{% for destination in trip.destinations.all %}
{{ destination.city_name }}
** This is terrible code -- How to fix that **
{% for key, value in activities_by_trips|dict_lookup:trip.id %}
{% if value %}
{% for key_prime, value_prime in value|dict_lookup:destination.id %}
{{ value_prime.description }}
{% endfor %}
{% endif %}
{% endfor %}
{% endfor %}
{% endfor %}
{% endblock %}
Kurz, kann mir bitte jemand helfen um eine Zusammenfassung von all den Reisen und Aktivitäten? Was ist der beste Weg, um zu erreichen, dass? Ist das Modell korrekt?
Dank!
InformationsquelleAutor Martin | 2012-02-26
Du musst angemeldet sein, um einen Kommentar abzugeben.
Gibt es viel Raum für Verbesserung. Durch die Verwendung von durch auf ManyToManyField können Sie explizit definieren Sie die join-Tabelle, die können wir bequem betrachten als ein einziger Besuch auf eine Stadt, die während einer bestimmten Reise. Bei diesem Besuch hatten wir Aktivitäten, also Aktivitäten sollten einen foreignkey zu einem Besuch ein.
Für jeden foreignkey in einer Tabelle, Django hinzufügen API-Komfort-manager für Mengen von Objekten auf der gegenüberliegenden Seite der Beziehung.
Destination
habenvisit_set
, aber so wirdTrip
. Ähnlich, da dervisit
foreignkey inActivity
jedem Besuch wird einactivity_set
.Ersten start mit den Modellen:
Dann ändern können
list_trip
ein bisschen, Hinzugefügt print_trip für Klarheit, was Los ist in Vorlage:Und schließlich die verbesserte Vorlage:
Gibt es noch einige mehr Raum für Verbesserung was Leistung und Performance betrifft. Beachten Sie, dass ich verwendet select_related. , Prefetch alle Ziele die zur Zeit Besuche abgerufen werden, so dass besuchen.Ziel.city_name, verursachen keine anderen db aufrufen. Allerdings funktioniert das nicht bei reverse ManyToMany Beziehungen (in unserem Fall sind alle Mitglieder der activity_set). Django 1.4 wird kommen mit neuen Methode namens prefetch_related, die aufgelöst wird.
In der Zwischenzeit, Lesen Sie auf Effiziente reverse-lookups für eine Idee wie man das noch weiter reduzieren Sie die Anzahl der DB-Zugriffe. In den Kommentaren einige leicht verfügbar Lösungen sind wie schon erwähnt gut.
InformationsquelleAutor astevanovic