Python Code in HTML

Sockets, TCP/IP, (XML-)RPC und ähnliche Themen gehören in dieses Forum
Sync32
User
Beiträge: 141
Registriert: Mittwoch 27. Januar 2010, 12:42

Guten Tag.
Wie bindet man Python-Code in Html Datein an?

Bei Php z.B. kann man es ja einfach per

<?php
...code ....
?>

machen. Wie ist es bei Python? Hab mir schon paar Beispiele angeguckt, die sahen so aus:

Code: Alles auswählen

{% block content %}
{% if mygogo %}
    <table>
    {% for xxx in adress_list %}
        <caption class="section">Adress</caption>
            <tr>
               <th scope="row"><a href="{{ xxx.get_absolute_url }}/admin/adressbook/myroject/{{ xxx.name }}/">{{ xxx.name }}</a></th>
            
    {% endfor %}
    </table>
    
{% else %}
    <p>lalalalla</p>

{% endblock %}
Mir ist es dennoch nicht ganz klar. Wie mache ich es, wenn ich z.b.

x=0
if x==0
<a img src="..." alt="bild1">
else
<a img src="..." alt="bild2">

einbinden möchte, wie gehe ich da am besten vor?
Benutzeravatar
Defnull
User
Beiträge: 778
Registriert: Donnerstag 18. Juni 2009, 22:09
Wohnort: Göttingen
Kontaktdaten:

PHP ist extra dafür entwickelt worden, in HTML eingebettet zu werden. Python funktioniert so nicht. Du willst eine Template-Sprache verwenden und dich noch einmal grundsätzlich darüber informieren, wie Web Applikationen in Python realisiert werden. Das unterscheidet sich nämlich maßgeblich vom üblichen Vorgenen mit PHP.
Bottle: Micro Web Framework + Development Blog
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Defnull hat geschrieben:... verwenden und dich noch einmal grundsätzlich darüber informieren, wie Web Applikationen in Python realisiert werden. Das unterscheidet sich nämlich maßgeblich vom üblichen Vorgenen mit PHP.
Du hast noch vergessen zu erwähnen: Ein Glück! ;-) SCNR

(Und die Existenz von Python Server Pages verschweigen wir besser mal :twisted: )
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Sync32, schau dir vielleicht einfach mal Bottle an. Das ist einfach und enthält auch eine simple Template-Funktion, in der du dann dein "if" programmieren kannst.

Das zitierte Beispiel zieht nach dem Template-System von Django aus. Wäre natürlich auch eine Lösung, gerade wenn man gerne ein komplettes Rahmenwerk haben möchte, ist aber overkill, wenn's nur schnell eine Webseite sein soll.

Ach ja, Django-Templates haben Jinja beeinflusst und das wiederum kann man auch mit Bottle benutzen.

Stefan
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

Sync32 hat geschrieben:Guten Tag.
Wie bindet man Python-Code in Html Datein an?
Gar nicht. Es geht nicht.

Das ist ein Punkt, mit dem PHP-Umsteiger immer hart zu kämpfen haben.
Sync32
User
Beiträge: 141
Registriert: Mittwoch 27. Januar 2010, 12:42

Erstmal danke für die Antworten

Naja "gar nicht" ist wahrscheinlich auch nicht ganz richtig.
Ich arbeite derzeit mit Django.

Und dort habe ich ausm Tutorial so eine Template Vorgabe:

Code: Alles auswählen

{% if latest_poll_list %}
    <ul>
    {% for poll in latest_poll_list %}
        <li><a href="#">{{ poll.question }}</a></li>
    {% endfor %}
    </ul>
{% else %}
    <p>No polls are available.</p>
{% endif %}

Wie man schwer erkennen kann, ist das eine Schleife, die alle Fragen "lädt" und auflistet.

Nun möchte ich wenn man den Link anklickt, das ein Text erscheint mit "Du hast Frage "X" angeklickt".

Habs wie folgt in dem Template und im view.py geändert:

Code: Alles auswählen

{% if latest_poll_list %}
    <ul>
    {% for poll in latest_poll_list %}
        <li><a href="#">{{ poll.question }}</a></li>
    {% endfor %}
    </ul>
{% else %}
    <p>No polls are available.</p>
{% endif %}
{% if presslink %}
<p> Du hast die Frage " {{ poll.question }} " angeklickt </p>
{% endif %}
Also das mit dem Text klappt schonmal. Wenn ich auf ein Link klicke, lädt er die selbe Seite nochmal und zeigt die letzte If Abfrage an.

Hab in der view.py einfach als return zurück gegeben:
return render_to_response('projectXXX/index.html', {.....'presslink':'presslink' } .....

Bloß er zeigt mir {{ poll.question }} nicht an Sondern nur den Text. Ist ja auch ganz klar, da er ja gar nicht weiß, welche Frage (welche ID) er laden soll.
Wie mache ich das am besten?
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

Sync32 hat geschrieben:Naja "gar nicht" ist wahrscheinlich auch nicht ganz richtig.
Doch.
Sync32 hat geschrieben:Ich arbeite derzeit mit Django.
Wenn du glaubst, dass das bei Django anders ist hast du Django nicht verstanden.
Sync32 hat geschrieben:

Code: Alles auswählen

{% if latest_poll_list %}
    <ul>
    {% for poll in latest_poll_list %}
        <li><a href="#">{{ poll.question }}</a></li>
    {% endfor %}
    </ul>
{% else %}
    <p>No polls are available.</p>
{% endif %}
Du hast hier aktuell kein Python-Problem sondern ein HTML-Problem. Wenn du dir den Quelltext der generierten Seite mal anschaust wirst du feststellen, dass alle Links nur nach "#" gehen. Du möchtest aber wahrscheinlich eher einen Link wie "/poll/{{ poll.id }}/" oder so ähnlich erstellen.

Dann musst du noch einen passenden Mapper für diese URL erstellen der auf eine View verweist die nun wiederum die passenden Daten ermittelt un dem dann auszugebenden Template mitgibt.
Sync32
User
Beiträge: 141
Registriert: Mittwoch 27. Januar 2010, 12:42

Ja ich weiß. ;)
War ja auch nur nen kleines Beispiel.
Wollte nun nicht mein "großen" Code hier reinposten.

Also per Schleifen kann ich mir meine Einträge anzeigen lassen:

Code: Alles auswählen

{% if presslink %}

		{% for prj in latest_adress_list %}	
			{% for cmd in prj.rang.all %}					
			<div class="module">Es wurde das Projekt  "{{ prj.name }}" mit dem Rang "{{ cmd.name }} geklickt!</div>
			{% endfor %}
		{% endfor %}
	
{% endif %}
Aber nun will ich ein bestimmten nur einbinden. Ich dachte so hier:

{% if presslink %}

{% for prj in latest_adress_list %}
{% for cmd in prj.rang.get(pk=2) %}
<div class="module">Es wurde die Adresse "{{ prj.name }}" mit dem Rang "{{ cmd.name }} geklickt!</div>
{% endfor %}
{% endfor %}

{% endif %}

Klappt aber nicht. Hab schon so vieles ausprobiert. Wie mache ich es, wenn ich den Eintrag mit der ID 2 anzeigen lassen will.
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

Sync32 hat geschrieben: Aber nun will ich ein bestimmten nur einbinden. Ich dachte so hier:

{% if presslink %}

{% for prj in latest_adress_list %}
{% for cmd in prj.rang.get(pk=2) %}
<div class="module">Es wurde die Adresse "{{ prj.name }}" mit dem Rang "{{ cmd.name }} geklickt!</div>
{% endfor %}
{% endfor %}

{% endif %}

Klappt aber nicht. Hab schon so vieles ausprobiert. Wie mache ich es, wenn ich den Eintrag mit der ID 2 anzeigen lassen will.
Du versuchst viel zu viel Programmlogik in das Template zu verlagern. Beschränke dich im Template auf die Anzeige und ermittele die Daten in der View[1]. Ich würde das wie folgt machen wenn ich einen Datensatz anzeigen möchte:

1) Alle for-Schleifen aus dem Template verbannen und nur

Code: Alles auswählen

<div class="module">Es wurde die Adresse "{{ prj.name }}" mit dem Rang "{{ cmd.name }} geklickt!</div>
stehen lassen.

2) In der aufrufenden View das prj ermitteln was du haben möchtest und an das Template übergeben.

Fertig.

_____
[1] Django hat statt MVC (Model, View, Controller) ein MTV (Model, Template, View) genanntes Konzept.
Sync32
User
Beiträge: 141
Registriert: Mittwoch 27. Januar 2010, 12:42

Ja sorry, hab ne zeitlang mit PHP gearbeitet. Deshalb die Angewohnheit :)

So hab das nun alles in der view gelöst und einfach nur ein Platzhalter eingebaut.
An der Stelle: Danke.

Nun habe ich auch mehrere Links auf der Template Site eingebaut.
Ich möchte das der Link, wo ich gerade bin, <b> fett </b> angezeigt wird.

Hatte mir folgende Lösung überlegt:
Das sind meien Links
....
{% for linky in prj.linkentry.all %}
<a href="....id=prj.ID" alt="....">Link </a>
{% endfor %}
Die aktuelle ID hab ich schon herausbekommen, also die hab ich in meiner view quasi "abgefangen" :)

Klappt auch soweit. Hab die auch schon testweise in meinem Template per {{ meinelinkid }} ausgegeben lassen und er zeigt mir richtigerweise immer die aktuelle Link-ID an, in der ich mich befinde.

Soweit mitgekommen? ^^

Eigentlich hätte ich einfach ne If-Abfrage im Template gemacht:
{% for linky in prj.linkentry.all %}
{%if prj.ID == meinlinkID %}
<a href="....id=prj.ID" alt="...."><b>Link </b></a>
{% else %}
<a href="....id=prj.ID" alt="....">Link </a>
{% endif %}
{% endfor %}
Geht so nicht? Der geht nur in den ELSE rein.
Warum?
Wenn ich testweise {%if 1 == 1 %} schreibe, gehts.
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

Sync32 hat geschrieben:Ja sorry, hab ne zeitlang mit PHP gearbeitet. Deshalb die Angewohnheit :)
Kenne ich. Von mir stammte mal ein großer Teil der deutschsprachigen Smarty-Dokumentation (damals, als Smarty noch ein Unterprojekt von PHP war). Gewisse Gewohnheiten legt man da nicht so schnell ab.
Sync32 hat geschrieben: Klappt auch soweit. Hab die auch schon testweise in meinem Template per {{ meinelinkid }} ausgegeben lassen und er zeigt mir richtigerweise immer die aktuelle Link-ID an, in der ich mich befinde.

Eigentlich hätte ich einfach ne If-Abfrage im Template gemacht:
{% for linky in prj.linkentry.all %}
{%if prj.ID == meinlinkID %}
...
meinelinkid vs. meinlinkID
Sync32
User
Beiträge: 141
Registriert: Mittwoch 27. Januar 2010, 12:42

/me, danke für deine schnellen Antworten.

Also auf "vs." wäre ich ja nie gekommen. Kann man diese "Html Python Platzhalter Tags" irgendwo nachlesen?! Die scheinen sich ja doch sehr von anderen zu unterscheiden
meinelinkid vs. meinlinkID
Habs gemacht aber leider kommt diese Fehlermeldung:
Exception Type: TemplateSyntaxError
Exception Value: Unused 'vs.' at end of if expression.
Exception Location: ...\django\template\smartif.py in parse, line 178
Hier mein Code:
{% if prj.id vs. meinlinkID %}
<p> Kein Link </p>
{% else %}
<a href"....">Ein Link </a>
{% endif %}
Hab auch schon normal
{% if 2 vs. 3 %}

ausprobiert, kommt aber auch die Meldung :(
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

Sync32 hat geschrieben:Also auf "vs." wäre ich ja nie gekommen.
Oh, da habe ich mich wohl unklar ausgedrückt. Mit vs. meinte ich versus, was wiederum die Bedeutung von gegen bzw. gegenüber hat. Ich habe den Ausdruck wohl fälschlicherweise als allgemeiner bekannt angenommen (such mal bei Google nach "ali vs. foreman").

Was ich meinte ist, dass du einmal meinelinkid verwendest und das andere Mal meinlinkID.

Als Literatur zu Django kann ich übrigens wärmstens das Buch "The Definitive Guide to Django - Web Development done right" von Adrian Holovaty und Jacob Kaplan-Moss empfehlen. Ich besitze es sowohl als Printversion wie auch zum unkomplizierteren Mitnehmen in elektronischer Form und bin sehr glücklich damit.
Sync32
User
Beiträge: 141
Registriert: Mittwoch 27. Januar 2010, 12:42

Naja viell. hab ich mich ja auch etwas unklar augedrückt, mit meinen zusammengebastelten Beispielen. ^^

Also frage ich mal allgemeiner:

Ich habe in meinem Template zwei {{ Platzhalter }} , wo jeweils eine Zahl hinter steckt.

If Abfragen sehen wie folgt aus:
{% if X %}
......
{% endif %}
Richtig?

Nun möchte ich eine If-Abfrage machen, die nur eintreten soll, wenn zwei Platzhalter den gleichen Inhalt haben. Aus meinen bisherigen Kenntnissen hätte ich es so geschrieben:
{% if platzhalter1 == platzhalter2 %}
<p> Die beiden Platzhalter sind gleich :)
{% endif %}
Das funktioniert aber leider nicht. Es kommt aber auch keine Fehlermeldung.
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

Sync32 hat geschrieben: Nun möchte ich eine If-Abfrage machen, die nur eintreten soll, wenn zwei Platzhalter den gleichen Inhalt haben. Aus meinen bisherigen Kenntnissen hätte ich es so geschrieben:
{% if platzhalter1 == platzhalter2 %}
<p> Die beiden Platzhalter sind gleich :)
{% endif %}
Diese Syntax ist aktuell laut Dokumentation für Django 1.1 nicht vorgesehen.

Django 1.2 wird diese Syntax erlauben.
Sync32
User
Beiträge: 141
Registriert: Mittwoch 27. Januar 2010, 12:42

Ich habe ja Version 1.2.
Das habe ich in der view stehen:

...
changeimg = project_id
...

Da bekommt die Variabel ihre Nr. zugewiesen. Klappt auch. Habe sie mal zum testen einfach nur im Html Document ausgeben lassen. Alles wunderbar.

<p> Der Inhalt ist {{ changeimg }} </p>
Dort wird immer die richtige Zahl angegeben.

{% for .....

{% if prj.id == changeimg %}
....
klappt aber nicht :(

Wenn ich nun z.B. in der view die Zahl manuell eingebe:
changeimg = 4 oder so

Dann geht er in die If Abfrage rein....
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Sync32 hat geschrieben: {% if prj.id == changeimg %}
....
klappt aber nicht :(
Kann das an verschiedenen Typen liegen?
So in dieser Richtung:

Code: Alles auswählen

In [10]: "2" == 2
Out[10]: False
Sync32
User
Beiträge: 141
Registriert: Mittwoch 27. Januar 2010, 12:42

Hab ich auch schon dran gedacht, dass es viell am Typ liegt. Aber das erste, was ich als C++/PHP User gelernt habe, dass Python keine Typ Deklaration braucht :D

changeimg = project_id

Kann ich da irgendwie denn sagen, dass der Inhalt von project_id als int-typ behandeln soll.?!
Oder wie meint ihr, könnte man das Problem noch lösen
Darii
User
Beiträge: 1177
Registriert: Donnerstag 29. November 2007, 17:02

Sync32 hat geschrieben:Hab ich auch schon dran gedacht, dass es viell am Typ liegt. Aber das erste, was ich als C++/PHP User gelernt habe, dass Python keine Typ Deklaration braucht :D
Nur weil du sie nicht deklarieren must, heißt das nicht, dass sie nicht existieren. Anders als PHP ist Python streng typisiert. Das heißt es gibt keine impliziten, inkonsistenten Typumwandlungen.
Kann ich da irgendwie denn sagen, dass der Inhalt von project_id als int-typ behandeln soll.?!
Gar nicht. typecasts gibt es in Python nicht. Du kannst aber aus project_id in einen Integer erstellen. Für Strings kannst du dazu einfach den String an den Konstructor von `int` übergeben.

Code: Alles auswählen

changeimg == int(project_id)
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

Sync32 hat geschrieben:Hab ich auch schon dran gedacht, dass es viell am Typ liegt. Aber das erste, was ich als C++/PHP User gelernt habe, dass Python keine Typ Deklaration braucht :D
Die Typdeklaration erfolgt implizit.

Probier es aus, vielleicht funktioniert es ja. Ich kann es hier nicht testen da ich Django in der Version 1.1 habe. Die aktuelle 1.2 alpha 1 wollte ich mir noch nicht antun.
Antworten