Seite 1 von 3
Daten aus zwei Klassen in ein template
Verfasst: Freitag 23. Januar 2015, 09:38
von django-yip
Hallo zusammen,
ich möchte gern Daten aus zwei Klassen in ein template bekommen, welche ich vom Admin-Bereich per request angefordert hab.
Die erste Klasse:
Code: Alles auswählen
class sim(models.Model):
nummer = models.CharField('SIM-Kartenummer',max_length=80,unique=True)
pin = models.CharField('PIN',max_length=4,null=True,blank=True)
pin2 = models.CharField('PIN2',max_length=4,null=True,blank=True)
puk = models.CharField('PUK',max_length=8,null=True,blank=True)
puk2 = models.CharField('PUK2',max_length=8,null=True,blank=True)
mobilfunknummer = models.ForeignKey('mobilfunknummer', verbose_name='Mobilfunknummer')
...
Und dann noch eine zweite Klasse
Code: Alles auswählen
class vertrag(models.Model):
mobilfunknummer = models.ForeignKey('mobilfunknummer', verbose_name="Mobilfunknummer")
grundtarif = models.ForeignKey('grundtarife', verbose_name="Grundtarif")
...
class grundtarife(models.Model):
grundtarif = models.CharField('Grundtarif',max_length=80,unique=False)
..
Die Daten von der ersten Klasse ('sim') bekomme ich per:
Code: Alles auswählen
def export_as_html(modeladmin, request, queryset):
response = HttpResponse(content_type="text/html")
entries = queryset
return render_to_response('export.html', {'entries': entries})
ins template.
Code: Alles auswählen
<div id="content">
{% block content %}
<br>
{% for e in entries %}
{{ e.mobilfunknummer }}
{{ e.nummer }}
{{ e.pin }}
Jetzt würde ich gern ins template "export.html" auch den passende Ausgabe vom "grundtarif" haben, welche mit der Mobilfunknummer gekoppelt ist.
Jemand eine Idee wie das aussehen muss?
Danke.
Re: Daten aus zwei Klassen in ein template
Verfasst: Freitag 23. Januar 2015, 16:54
von jerch
@django-yip:
Ich gehe mal davon aus, dass Du überall bei den ForeignKeys eigentlich OneToOneFields haben möchtest, da z.B. eine Telefonnummer nicht an mehrere SIMs gebunden sein kann. Das kannst Du zwar auch mit ForeignKeys und einem UNIQUE abbilden, geht aber mit dem OneToOneField komfortabler.
An die Daten kommst Du im template über die Rückrelationen, welche bei ForeignKeys QuerySets liefern und daher iteriert werden müssen. OneToOneField liefert nur die eine Entsprechung.
PS: Ich geh davon aus, dass Du django nutzt - bitte das nächste Mal mit vermerken.
Re: Daten aus zwei Klassen in ein template
Verfasst: Samstag 24. Januar 2015, 13:48
von django-yip
jerch hat geschrieben:@django-yip:
da z.B. eine Telefonnummer nicht an mehrere SIMs gebunden sein kann.
Eine Mobilfunknummer kann mehrere Sim Karten haben.
jerch hat geschrieben:
An die Daten kommst Du im template über die Rückrelationen, welche bei ForeignKeys QuerySets liefern und daher iteriert werden müssen.
Hast du ein Beispiel dafür?
jerch hat geschrieben:
PS: Ich geh davon aus, dass Du django nutzt - bitte das nächste Mal mit vermerken.
Ja sorry, hab django im Einsatz und noch neuling in python und django.
Re: Daten aus zwei Klassen in ein template
Verfasst: Samstag 24. Januar 2015, 14:51
von BlackJack
Re: Daten aus zwei Klassen in ein template
Verfasst: Montag 26. Januar 2015, 10:29
von django-yip
Wenn ich es so,
Code: Alles auswählen
def export_as_html(modeladmin, request, queryset):
response = HttpResponse(content_type="text/html")
entries = queryset
b = vertrag.objects.get()
b.grundtarif(vertrag='entries').all()
return render_to_response('export.html', {'entries': entries})
probiere, kommt die Fehlermeldung:
Exception Value:
'grundtarife' object is not callable
Jemand noch ne Idee, wo mein Fehler sein kann?
Re: Daten aus zwei Klassen in ein template
Verfasst: Montag 26. Januar 2015, 10:46
von BlackJack
@django-yip: Ich denke Du probierst entschieden zu viel herum ohne zu wissen was Du da eigentlich tust. Beschreib doch mal was bei Deinem letzten Codebeispiel genau passiert und damit auch warum diese Ausnahme kommt. Was genau bewirkt welche Zeile? Welche Datentypen haben die Ergebnisse der jeweiligen Teilausdrücke? `vertrag`? `vertrag.objects`?, `vertrag.objects.get()`? Was ist das jeweils für ein Wert von welchem Typ?
Re: Daten aus zwei Klassen in ein template
Verfasst: Montag 26. Januar 2015, 11:49
von django-yip
@BlackJack,
wenn ich wüßte was ich genau tun muss, würde ich nicht seit Freitag rätsel
Aber ich merk schon, ohne die große Erfahrung in Python zu haben komme ich hier nicht weiter. Nur das Django Tutorial durch zu gehen ist nicht genug.
Re: Daten aus zwei Klassen in ein template
Verfasst: Montag 26. Januar 2015, 12:37
von jerch
@django-yip:
Du musst die Dokumentation schon aufmerksam lesen. Dein `vertrag.objects.get()` z.B. wird fehlschlagen, wenn es keinen oder mehrere Einträge in der Tabelle gibt, welche die Kritierien erfüllen (da Du keine Kritierien gesetzt hast, wird alles gefunden). Ansonsten liefert `objects.get` immer nur genau eine Entsprechung, auf dem Model `vertrag` halt ein vertrag-Objekt. Das bindest Du an `b`, damit ist `b.grundtarif` das grundtarife-Objekt am vertrag-Objekt `b`. Das ist nicht aufrufbar - was sollte Deiner Meinung nach passieren bei einem solchen Aufruf?
Re: Daten aus zwei Klassen in ein template
Verfasst: Montag 26. Januar 2015, 14:03
von django-yip
jerch hat geschrieben:@django-yip:
- was sollte Deiner Meinung nach passieren bei einem solchen Aufruf?
@jerch: Im Besten Fall den Grundtarif, der per queryset ausgewählten Mobilfunknummer.
Re: Daten aus zwei Klassen in ein template
Verfasst: Montag 26. Januar 2015, 14:13
von BlackJack
@django-yip: Die Frage war jetzt wohl weniger nach dem was Du möchtest, sondern was in dem konkreten Fall passieren sollte denn das Attribut ist ja ganz offensichtlich kein Queryset *und* wenn es eines wäre, könnte man es trotzdem nicht aufrufen!
Re: Daten aus zwei Klassen in ein template
Verfasst: Montag 26. Januar 2015, 16:07
von jerch
@django-yip:
Das verstehende Lesen der Doku (django und evtl. Python-Grundlagen) können wir Dir nicht abnehmen. Der django-ORM funktioniert so, dass Relationen, welche nur ein Objekt enthalten können, dieses direkt zurückgegeben wird, z.B. Vorwärtsrelation bei ForeignKeys (grr, das steht so alles in der Doku):
Code: Alles auswählen
class Foo(models.Model):
bar = models.ForeignKey(Bar)
baz = models.ForeignKey(Baz, related_name='foos')
popels = models.ManyToManyField(Popel, related_name='foos')
...
# foo ist ein Foo-Objekt mit pk = 1 aus der DB bzw. raise DoesNotExist, falls es das nicht gibt
foo = Foo.objects.get(pk=1)
# foo.bar/foo.baz ist das Bar/Baz-Objekt, was mit foo verknüpft ist,
# ein ForeignKey-Vorwärtsrelation ist single, daher ist bar direkt dieses Objekt
foo.bar # bar an foo
foo.baz # baz an foo
# Rückrelationen (was hier passiert, dafür hat BlackJack dir sogar die Doku-Url spendiert)
# bei ForeignKey sind die Rückrelationen nicht single und daher QuerySets
# Bar-Objekt mit pk=1
bar = Bar.objects.get(pk=1)
# alle foos mit Foo.bar = bar - der Name mit <attr_name>_set ist ein Django default
bar.foo_set.all()
# und kann mit related_name überschrieben werden (siehe Foo oben):
baz = Baz.objects.get(pk=1)
baz.foos.all()
# Bei ManyToMany sind beide Richtungen nicht single, daher ist auch die Vorwärtsrelation ein QuerySet
foo.popels.all() # alle popels an foo
# und von Popel-Seite
popel = Popel.objects.get(pk=1)
popel.foos.all() # alle foos an popel
Re: Daten aus zwei Klassen in ein template
Verfasst: Dienstag 27. Januar 2015, 11:04
von django-yip
mhhh
Code: Alles auswählen
def export_as_html(modeladmin, request, queryset):
response = HttpResponse(content_type="text/html")
entries = queryset
mobilfunknummer = mobilfunknummer.objects.get(pk=1)
mobilfunknummer.sim_set.all()
return render_to_response('export.html', {'entries': entries})
Ich hab jetzt versucht von Class Sim eine Rückrelation zu bilden mit der mobilfunknummer. Klappt aber immer noch nicht.
Fehlermeldung:
Exception Type: UnboundLocalError
Exception Value:
local variable 'mobilfunknummer' referenced before assignment
Re: Daten aus zwei Klassen in ein template
Verfasst: Dienstag 27. Januar 2015, 13:06
von BlackJack
@django-yip: In Zeile 5 steht *rechts* von der Zuweisung `mobilfunknummer`, der Name wird ganz offensichtlich nirgends definiert. Du willst den ja in der Zeile erst definieren, denn er steht ja auch links von der Zuweisung.
Wieder die Frage: was soll da für ein Wert und von welchem Typ stehen wo jetzt das undefinierte `mobilfunknummer` steht? Der Allgemeine Typ ist ja im Grunde durch den Zugriff auf `objects` festgelegt: Da müsste ein `Model`-Wert stehen damit das klappt.
Re: Daten aus zwei Klassen in ein template
Verfasst: Dienstag 27. Januar 2015, 13:46
von django-yip
Code: Alles auswählen
class Foo(models.Model):
bar = models.ForeignKey(Bar)
baz = models.ForeignKey(Baz, related_name='foos')
popels = models.ManyToManyField(Popel, related_name='foos')
...
# Rückrelationen (was hier passiert, dafür hat BlackJack dir sogar die Doku-Url spendiert)
# bei ForeignKey sind die Rückrelationen nicht single und daher QuerySets
# Bar-Objekt mit pk=1
bar = Bar.objects.get(pk=1)
Aber dann ist das Beispiel auch nicht korrekt?!
bar wäre bei mir mobilfunknummer ein ForeignKey aus der Class Sim.
Code: Alles auswählen
# alle foos mit Foo.bar = bar - der Name mit <attr_name>_set ist ein Django default
bar.foo_set.all()
Und hier wäre bar.foo_set.all() bei mir mobilfunknummer(ForeignKey).sim(class)_set.all()
Re: Daten aus zwei Klassen in ein template
Verfasst: Dienstag 27. Januar 2015, 14:42
von Sirius3
@django-yip: die ganze Funktion ergibt doch so gar keinen Sinn. Was ist modeladmin und queryset? Warum willst Du von einer Mobilfunknummer immer den Eintrag mit pk=1 (unter der Annahme, es gäbe ein Model "Mobilfunknummer" das Du hier benutzt)? "all" ist eine Funktion, die alle Elemente eines Queries zurückgibt. Mit dieser Liste fängst Du aber gar nichts an. Kannst Du mal vollständige Beispiele posten, die man auch verstehen kann und die Sinn machen?
Re: Daten aus zwei Klassen in ein template
Verfasst: Dienstag 27. Januar 2015, 14:45
von BlackJack
@django-yip: Das Beispiel ist nicht falsch weil `Bar` hier die `Model`-Klasse ist. Die Definition wird nicht gezeigt, aber ja bei der Defintion vom Klassenattribut `Foo.bar` benutzt, also sollte man davon ausgehen dass es existiert also irgendwo davor importiert wird oder ein ``class Bar(Model): …`` weiter oben steht.
Du solltest Dir vielleicht auch mal angewöhnen der Namenskonvention zu folgen das man Klassennamen in MixedCase statt in kleinbuchstaben schreibt.
Man kann nicht einfach so auf Namen zugreifen die in anderen Namensräumen definiert sind. Es könnte ja auch mehrere Klassen mit einem `bar`-Attribut geben, welches sollte denn da dann genommen werden? Auf magische Weise das welches man haben möchte?
Selbst wenn man das könnte, welcher Wert wäre denn dann `mobilfunknummer`? Also welche Mobilfunknummer ganz konkret? Und da Du alles klein schreibst gibt es denn auch eine `Model`-Klasse mit dem Namen? Warum ist die nicht definiert? Denn dann ginge ja wieder die Zeile die Du da stehen hast. (Ob sie sinnvoll ist hängt dann noch mal davon ab was dort eigentlich gemacht werden soll.)
Re: Daten aus zwei Klassen in ein template
Verfasst: Dienstag 27. Januar 2015, 14:57
von django-yip
Das wird wohl dann der Fehler sein, da bei mir mobilfunknummer einmal ForeignKey ist einmal eine Model Klasse ist. Werde mal versuchen dies so umzuändern, dass Model-Klassen immer mit groß Buchstaben beginnen.
Re: Daten aus zwei Klassen in ein template
Verfasst: Dienstag 27. Januar 2015, 15:04
von BlackJack
@django-yip: Das ist zwar nicht gut wenn die Klassen nicht den Namenskonventionen entsprechen, aber wenn es die Klasse mit dem Namen gibt, müsstest Du halt den lokalen Namen anders nennen damit der lokale Name nicht die Klasse überdeckt. Dass das Klassenattribut irgendwo auch so heisst ist egal. Das ist ein anderer Namensraum.
Und es gilt natürlich das was Sirius3 über die Sinnhaftigkeit des Codes und den unbenutzen Argumenten gesagt hat.
Re: Daten aus zwei Klassen in ein template
Verfasst: Mittwoch 28. Januar 2015, 07:32
von django-yip
Sirius3 hat geschrieben:Was ist modeladmin und queryset?
So steht es in der Doku ->
https://docs.djangoproject.com/en/1.7/r ... n/actions/
Hab mir nur daran gehalten. Und es funktioniert ja auch, bloß Werte aus einer zweiten DB zu erhalten noch nicht.
Re: Daten aus zwei Klassen in ein template
Verfasst: Mittwoch 28. Januar 2015, 11:18
von jerch
@django-yip:
Die Admin-Klassen sind eine Abstraktion von Django, welche die generische Darstellung von Modeldaten unter Beachtung von Benutzerrechten ermöglichen. Das ist zunächst eine tolle Vereinfachung und macht es möglich, schnell Modeldaten zur Anzeige und in Formularen zur Änderung anzubieten. So generiert Django den Adminbereich. Der Hund liegt dort begraben, wo man mit den Adminklassen mehr machen will, als der Standardweg vorsieht - die APIs sind z.T. undokumentiert und man verlässt die klassische View-Template-Trennung, welche Django fürs Programmieren von Webseiten vorsieht. Du musst hier sehr genau wissen, was Du erreichen willst, z.B. ist die Erweiterung eines AdminForms mit Standard-Subformularen gut möglich (sogenannte Inlineformulare), spezielle Anforderungen aber mitunter sehr schwierig über die Adminklassen zu implementieren. Im Zweifelsfalle ist die Lösung, einen eigenen benutzerdefinierten View zu erstellen, einfacher als die Integration über die Adminklassen. Diesen Hinweis findest Du auch in der Doku.
django-yip hat geschrieben:Und es funktioniert ja auch, bloß Werte aus einer zweiten DB zu erhalten noch nicht.
Du meinst sicherlich ein zweites Model und nicht DB, eine zweite DB wäre eine andere Datenbankverbindung.