Es gibt ein paar Ansätze, die Sie auf den Umgang mit den QuerySet
s von „Mischmodelle nehmen "dass Sie erhalten, wenn Sie diese Art von Abfrage durchführen. Vieles hängt von deinem ultimativen Ziel ab.
Der "einfache und dumme" Weg, den ich oft nutze, besteht darin, die Ergebnisse mit Utility-Funktionen zu verwalten. Wenn Sie beispielsweise das Ergebnis Build.objects.filter(project="myproject")
in einer Vorlage verarbeiten möchten, können Sie benutzerdefinierte Vorlagen-Tags oder Filter verwenden, um spezielle Maßnahmen zu ergreifen. Es sei angenommen, in dem unten stehenden Code build_objects
enthält das Ergebnis des Filters():
{% for build in build_objects %}
{% if build|is_custom_build %}
<p>This is a custom build of custom type {{ build.custom_build.custom_type }}!</p>
{% endif %}
<p>This is a custom build OR a standard build</p>
{% endfor %}
Das offensichtliche Problem hier ist, wenn Sie zahlreiche Unterklassen haben, schreiben Template Filter unpraktisch sein kann oder langweilig wachsen. Meiner Erfahrung nach habe ich jedoch in der Regel höchstens ein halbes Dutzend Unterklassen, daher ist das nicht immer ein Problem.
Sie könnten auch eine parametrisierte Filter wie so schreiben:
{% if build|is_of_buildtype:"custom_build" %}
Mit dem Code-Filter wie folgt:
def is_of_buildtype_filter(value, arg):
if hasattr(value, arg): return True
else: return False
Dieser Filter einfach auf das Vorhandensein des Arguments auf das als Attribut überprüft build
Objekt (als value
übergeben). Die Argument-Zeichenfolge sollte der Name der automatisch generierten OneToOneField
sein, die Sie ermitteln möchten, in diesem Fall custom_build
.
Für Ansichtscode funktionieren ähnliche Arten von Hilfsfunktionen auf die gleiche Weise, sind aber noch einfacher, da Sie keine benutzerdefinierten Filter oder Tags schreiben müssen.
Dieser Ansatz funktioniert in vielen Fällen, aber es gibt kompliziertere Szenarien, in denen es möglicherweise nicht praktikabel ist. Leider kann Django Ihnen nativ keine QuerySet
liefern, die Unterklasseninstanzen enthält, wenn Sie Operationen für die Basisklasse ausführen (dh eine QuerySet
, die wirklich "gemischte Modelle" enthält). Dies kann in Situationen erforderlich sein, in denen die Verarbeitung der Ergebnisse mit Hilfsfunktionen nicht möglich ist.
Ich persönlich vermeide diese Situationen völlig, normalerweise, indem ich mein Modelldesign überdenken. Aber wenn das nicht möglich ist, gibt es viele interessante Lösungsversuche, zB Inheritance MixIn. Es gibt auch einige Django-Schnipsel zum Thema.Beachten Sie jedoch, dass fast jede Lösung wie diese leistungsbegrenzt ist.
Ich schätze die Zeit, die Sie in diesen Kommentar schreiben. Ich war wirklich mehr daran interessiert, wie ich das in Code statt in Templates machen konnte. Ich wünschte, ich könnte beide Antworten akzeptieren, da ich deinen hasattr-Code als nützlich empfunden habe, aber ich habe stattdessen deine Antwort hochgestuft. – titaniumdecoy