One place for hosting & domains

      Verwenden der PDO-PHP-Erweiterung zur Durchführung von MySQL-Transaktionen in PHP unter Ubuntu 18.04


      Der Autor wählte die Kooperation Open Sourcing Mental Illness, um eine Spende im Rahmen des Programms Write for DOnations zu erhalten.

      Einführung

      Eine MySQL-Transaktion ist eine Gruppe von logisch zusammenhängenden SQL-Befehlen, die in der Datenbank als eine einzige Einheit ausgeführt werden. Transaktionen werden verwendet, um die ACID (Atomicity, Consistency, Isolation und Durability)-Konformität in einer Anwendung durchzusetzen. Dabei handelt es sich um eine Reihe von Standards, die die Zuverlässigkeit der Verarbeitungsvorgänge in einer Datenbank regeln.

      Atomarität (Atomicity) gewährleistet den Erfolg zusammengehöriger Transaktionen oder einen vollständigen Ausfall, wenn ein Fehler auftritt. Konsistenz (Consistency) garantiert die Gültigkeit der an die Datenbank übermittelten Daten gemäß der definierten Geschäftslogik. Isolierung (Isolation) ist die korrekte Ausführung von gleichzeitigen Transaktionen, wobei sichergestellt wird, dass die Auswirkungen verschiedener Clients, die sich mit einer Datenbank verbinden, sich nicht gegenseitig beeinflussen. Dauerhaftigkeit (Durability) stellt sicher, dass logisch zusammenhängende Transaktionen dauerhaft in der Datenbank verbleiben.

      Über eine Transaktion ausgegebene SQL-Anweisungen sollten entweder erfolgreich sein oder ganz fehlschlagen. Wenn eine der Abfragen fehlschlägt, macht MySQL die Änderungen rückgängig und sie werden niemals in die Datenbank übertragen.

      Ein gutes Beispiel zum Verständnis der Funktionsweise von MySQL-Transaktionen ist eine E-Commerce-Website. Wenn ein Kunde eine Bestellung aufgibt, fügt die Anwendung je nach Geschäftslogik Datensätze in mehrere Tabellen ein, wie beispielsweise: orders und orders_products. Mehrtabellen-Datensätze, die sich auf eine einzelne Bestellung beziehen, müssen als eine einzige logische Einheit atomar an die Datenbank gesendet werden.

      Ein weiterer Anwendungsfall ist in einer Bankanwendung. Wenn ein Kunde Geld überweist, werden einige Transaktionen an die Datenbank gesendet. Das Konto des Senders wird belastet und dem Konto der Partei des Empfängers gutgeschrieben. Die beiden Transaktionen müssen gleichzeitig bestätigt werden. Wenn eine von ihnen fehlschlägt, kehrt die Datenbank in ihren ursprünglichen Zustand zurück, und es sollten keine Änderungen auf der Festplatte gespeichert werden.

      In diesem Tutorial werden Sie die PDO-PHP-Erweiterung verwenden, die eine Schnittstelle für die Arbeit mit Datenbanken in PHP bietet, um MySQL-Transaktionen auf einem Ubuntu 18.04-Server durchzuführen.

      Voraussetzungen

      Bevor Sie beginnen, benötigen Sie Folgendes:

      Schritt 1 — Erstellen einer Beispieldatenbank und von Tabellen

      Als Erstes erstellen Sie eine Beispieldatenbank und fügen einige Tabellen hinzu, bevor Sie mit MySQL-Transaktionen zu arbeiten beginnen. Melden Sie sich zunächst als root bei Ihrem MySQL-Server an:

      Wenn Sie dazu aufgefordert werden, geben Sie Ihr MySQL-Root-Passwort ein und drücken Sie ENTER, um fortzufahren. Erstellen Sie dann eine Datenbank. Für die Zwecke dieses Tutorials werden wir die Datenbank sample_store nennen:

      • CREATE DATABASE sample_store;

      Sie sehen die folgende Ausgabe:

      Output

      Query OK, 1 row affected (0.00 sec)

      Erstellen Sie einen Benutzer namens sample_user für Ihre Datenbank. Denken Sie daran, PASSWORD durch einen starken Wert zu ersetzen:

      • CREATE USER 'sample_user'@'localhost' IDENTIFIED BY 'PASSWORD';

      Erteilen Sie Ihrem Benutzer uneingeschränkte Berechtigungen für die Datenbank sample_store:

      • GRANT ALL PRIVILEGES ON sample_store.* TO 'sample_user'@'localhost';

      Laden Sie abschließend die MySQL-Berechtigungen neu:

      Sobald Sie Ihren Benutzer angelegt haben, sehen Sie die folgende Ausgabe:

      Output

      Query OK, 0 rows affected (0.01 sec) . . .

      Mit der vorhandenen Datenbank und dem Benutzer können Sie jetzt mehrere Tabellen erstellen, um zu demonstrieren, wie MySQL-Transaktionen funktionieren.

      Melden Sie sich vom MySQL-Server ab:

      Sobald das System Sie abmeldet, sehen Sie die folgende Ausgabe:

      Output

      Bye.

      Melden Sie sich dann mit den Anmeldeinformationen des Benutzers sample_user an, den Sie gerade angelegt haben:

      • sudo mysql -u sample_user -p

      Geben Sie das Passwort für den sample_user ein und drücken Sie ENTER, um fortzufahren.

      Wechseln Sie zu sample_store, um sie zur aktuell ausgewählten Datenbank zu machen:

      Sobald die Datenbank ausgewählt ist, sehen Sie die folgende Ausgabe:

      Output

      Database Changed.

      Erstellen Sie als Nächstes eine Tabelle products:

      • CREATE TABLE products (product_id BIGINT PRIMARY KEY AUTO_INCREMENT, product_name VARCHAR(50), price DOUBLE) ENGINE = InnoDB;

      Mit diesem Befehl wird eine Tabelle products mit einem Feld namens product_id erstellt. Verwenden Sie einen Datentyp BIGINT, der einen großen Wert von bis zu 2^63-1 aufnehmen kann. Sie verwenden dasselbe Feld als PRIMARY KEY zur eindeutigen Identifizierung von Produkten. Das Schlüsselwort AUTO_INCREMENT weist MySQL an, den nächsten numerischen Wert zu erzeugen, wenn neue Produkte eingefügt werden.

      Das Feld product_name ist vom Typ VARCHAR und kann bis zu 50 Buchstaben oder Zahlen enthalten. Für den Produktpreis (price) verwenden Sie einen Datentyp DOUBLE, um Fließkommaformate in Preisen mit Dezimalzahlen zu berücksichtigen.

      Zuletzt verwenden Sie die InnoDB als ENGINE, weil sie im Gegensatz zu anderen Speicher-Engines wie MyISAM MySQL-Transaktionen komfortabel unterstützt.

      Sobald Sie Ihre Tabelle products erstellt haben, erhalten Sie die folgende Ausgabe:

      Output

      Query OK, 0 rows affected (0.02 sec)

      Fügen Sie als Nächstes einige Artikel zur Tabelle products hinzu, indem Sie die folgenden Befehle ausführen:

      • INSERT INTO products(product_name, price) VALUES ('WINTER COAT','25.50');
      • INSERT INTO products(product_name, price) VALUES ('EMBROIDERED SHIRT','13.90');
      • INSERT INTO products(product_name, price) VALUES ('FASHION SHOES','45.30');
      • INSERT INTO products(product_name, price) VALUES ('PROXIMA TROUSER','39.95');

      Nach jeder Operation INSERT sehen Sie eine Ausgabe ähnlich der folgenden:

      Output

      Query OK, 1 row affected (0.02 sec) . . .

      Überprüfen Sie dann, ob die Daten der Tabelle products hinzugefügt wurden:

      Sie sehen eine Liste mit den vier von Ihnen eingefügten Produkten:

      Output

      +------------+-------------------+-------+ | product_id | product_name | price | +------------+-------------------+-------+ | 1 | WINTER COAT | 25.5 | | 2 | EMBROIDERED SHIRT | 13.9 | | 3 | FASHION SHOES | 45.3 | | 4 | PROXIMA TROUSER | 39.95 | +------------+-------------------+-------+ 4 rows in set (0.01 sec)

      Als Nächstes erstellen Sie eine Tabelle customers, die grundlegende Informationen über Kunden enthält:

      • CREATE TABLE customers (customer_id BIGINT PRIMARY KEY AUTO_INCREMENT, customer_name VARCHAR(50) ) ENGINE = InnoDB;

      Wie in der Tabelle products verwenden Sie für die customer_id den Datentyp BIGINT, wodurch sichergestellt wird, dass die Tabelle viele Kunden mit bis zu 2^63-1 Datensätzen unterstützt. Das Schlüsselwort AUTO_INCREMENT erhöht den Wert der Spalten, sobald Sie einen neuen Kunden einfügen.

      Da die Spalte customer_name alphanumerische Werte akzeptiert, verwenden Sie den Datentyp VARCHAR mit einer Beschränkung von 50 Zeichen. Auch hier verwenden Sie die InnoDB Storage ENGINE zur Unterstützung von Transaktionen.

      Nachdem Sie den vorherigen Befehl zum Anlegen der Tabelle customers ausgeführt haben, sehen Sie die folgende Ausgabe:

      Output

      Query OK, 0 rows affected (0.02 sec)

      Sie fügen der Tabelle drei Musterkunden hinzu. Führen Sie die folgenden Befehle aus:

      • INSERT INTO customers(customer_name) VALUES ('JOHN DOE');
      • INSERT INTO customers(customer_name) VALUES ('ROE MARY');
      • INSERT INTO customers(customer_name) VALUES ('DOE JANE');

      Sobald die Kunden hinzugefügt wurden, sehen Sie eine Ausgabe ähnlich der folgenden:

      Output

      Query OK, 1 row affected (0.02 sec) . . .

      Überprüfen Sie dann die Daten in der Tabelle customers:

      Sie sehen eine Liste mit den drei Kunden:

      Output

      +-------------+---------------+ | customer_id | customer_name | +-------------+---------------+ | 1 | JOHN DOE | | 2 | ROE MARY | | 3 | DOE JANE | +-------------+---------------+ 3 rows in set (0.00 sec)

      Anschließend erstellen Sie eine Tabelle orders, um die von verschiedenen Kunden aufgegebenen Bestellungen aufzuzeichnen. Führen Sie den folgenden Befehl aus, um die Tabelle orders zu erstellen:

      • CREATE TABLE orders (order_id BIGINT AUTO_INCREMENT PRIMARY KEY, order_date DATETIME, customer_id BIGINT, order_total DOUBLE) ENGINE = InnoDB;

      Verwenden Sie die Spalte order_id als PRIMARY KEY. Der Datentyp BIGINT ermöglicht Ihnen die Aufnahme von bis zu 2^63-1 Bestellungen und wird nach jeder Bestellungseinfügung automatisch erhöht. Das Feld order_date enthält das tatsächliche Datum und die tatsächliche Uhrzeit der Bestellung, daher verwenden Sie den Datentyp DATETIME. Die customer_id bezieht sich auf die zuvor von Ihnen erstellte Tabelle customers.

      Sie sehen die folgende Ausgabe:

      Output

      Query OK, 0 rows affected (0.02 sec)

      Da die Bestellung eines einzelnen Kunden mehrere Artikel enthalten kann, müssen Sie eine Tabelle orders_products erstellen, um diese Informationen zu speichern.

      Führen Sie den folgenden Befehl aus, um die Tabelle orders_products zu erstellen:

      • CREATE TABLE orders_products (ref_id BIGINT PRIMARY KEY AUTO_INCREMENT, order_id BIGINT, product_id BIGINT, price DOUBLE, quantity BIGINT) ENGINE = InnoDB;

      Verwenden Sie die ref_id als PRIMARY KEY, der nach jeder Einfügung eines Datensatzes automatisch erhöht wird. Die order_id und product_id beziehen sich auf die Tabelle orders und products. Die Spalte price ist vom Datentyp DOUBLE, um gleitende Werte aufzunehmen.

      Die Speicher-Engine InnoDB muss mit den zuvor erstellten Tabellen übereinstimmen, da sich die Bestellung eines einzelnen Kunden unter Verwendung von Transaktionen gleichzeitig auf mehrere Tabellen auswirkt.

      Ihre Ausgabe bestätigt die Erstellung der Tabelle:

      Output

      Query OK, 0 rows affected (0.02 sec)

      Sie werden vorerst keine Daten zu den Tabellen orders und orders_products hinzufügen. Dies geschieht jedoch später mit einem PHP-Skript, das MySQL-Transaktionen implementiert.

      Melden Sie sich vom MySQL-Server ab:

      Ihr Datenbankschema ist nun vollständig und Sie haben es mit einigen Datensätzen gefüllt. Nun werden Sie eine PHP-Klasse für die Handhabung von Datenbankverbindungen und MySQL-Transaktionen erstellen.

      Schritt 2 – Entwerfen einer PHP-Klasse zur Abwicklung von MySQL-Transaktionen

      In diesem Schritt erstellen Sie eine PHP-Klasse, die PDO (PHP Data Objects) zur Abwicklung von MySQL-Transaktionen verwendet. Die Klasse wird eine Verbindung zu Ihrer MySQL-Datenbank herstellen und Daten atomar in die Datenbank einfügen.

      Speichern Sie die Klassendatei im Stammverzeichnis Ihres Apache-Webservers. Erstellen Sie dazu mit Ihrem Texteditor eine Datei DBTransaction.php:

      • sudo nano /var/www/html/DBTransaction.php

      Fügen Sie dann den folgenden Code in die Datei ein: Ersetzen Sie PASSWORD mit dem in Schritt 1 erstellten Wert:

      /var/www/html/DBTransaction.php

      <?php
      
      class DBTransaction
      {
          protected $pdo;
          public $last_insert_id;
      
          public function __construct()
          {
              define('DB_NAME', 'sample_store');
              define('DB_USER', 'sample_user');
              define('DB_PASSWORD', 'PASSWORD');
              define('DB_HOST', 'localhost');
      
              $this->pdo = new PDO("mysql:host=" . DB_HOST . ";dbname=" . DB_NAME, DB_USER, DB_PASSWORD);
              $this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
              $this->pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
          }
      

      Zu Beginn der Klasse DBTransaction verwendet das PDO die Konstanten (DB_HOST, DB_NAME, DB_USER und DB_PASSWORD) zur Initialisierung und Verbindung mit der Datenbank, die Sie in Schritt 1 erstellt haben.

      Anmerkung: Da wir hier MySQL-Transaktionen in kleinem Maßstab demonstrieren, haben wir die Datenbankvariable in der Klasse DBTransaction deklariert. In einem großen Produktionsprojekt würden Sie normalerweise eine separate Konfigurationsdatei erstellen und die Datenbankkonstanten aus dieser Datei mit Hilfe einer PHP-Anweisung require_once laden.

      Als Nächstes legen Sie zwei Attribute für die Klasse PDO fest:

      • ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION: Dieses Attribut weist PDO an, eine Ausnahme auszulösen, wenn ein Fehler auftritt. Solche Fehler können zum Debugging protokolliert werden.
      • ATTR_EMULATE_PREPARES, false: Diese Option deaktiviert die Emulation vorbereiteter Anweisungen und erlaubt der MySQL-Datenbank-Engine, die Anweisungen selbst vorzubereiten.

      Fügen Sie nun den folgenden Code in Ihre Datei ein, um die Methoden für Ihre Klasse zu erstellen:

      /var/www/html/DBTransaction.php

      . . .
          public function startTransaction()
          {
              $this->pdo->beginTransaction();
          }
      
          public function insertTransaction($sql, $data)
          {
              $stmt = $this->pdo->prepare($sql);
              $stmt->execute($data);
              $this->last_insert_id = $this->pdo->lastInsertId();
          }
      
          public function submitTransaction()
          {
              try {
                  $this->pdo->commit();
              } catch(PDOException $e) {
                  $this->pdo->rollBack();
                  return false;
              }
      
                return true;
          }
      }
      

      Speichern und schließen Sie die Datei, indem Sie STRG + X, Y, dann ENTER drücken.

      Um mit MySQL-Transaktionen zu arbeiten, erstellen Sie in der Klasse DBTransaction drei Hauptmethoden: startTransaction, insertTransaction und submitTransaction.

      • startTransaction: Diese Methode weist PDO an, eine Transaktion zu starten, und schaltet Auto-Commit aus, bis ein Commit-Befehl ausgegeben wird.

      • insertTransaction: Diese Methode benötigt zwei Argumente. Die Variable $sql enthält die auszuführende SQL-Anweisung, während die Variable $data ein Array mit Daten ist, die an die SQL-Anweisung gebunden werden sollen, da Sie vorbereitete Anweisungen verwenden. Die Daten werden als Array an die Methode insertTransaction übergeben.

      • submitTransaction: Diese Methode bindet die Änderungen dauerhaft an die Datenbank, indem Sie einen Befehl commit() ausgibt. Wenn jedoch ein Fehler auftritt und die Transaktionen ein Problem haben, ruft die Methode die Methode rollBack() auf, um die Datenbank in ihren ursprünglichen Zustand zurückzuversetzen, falls eine PDO-Ausnahme ausgelöst wird.

      Ihre Klasse DBTransaction initialisiert eine Transaktion, bereitet die verschiedenen auszuführenden SQL-Befehle vor, und bindet schließlich die Änderungen atomar in die Datenbank ein, wenn es keine Probleme gibt. Andernfalls wird die Transaktion rückgängig gemacht. Darüber hinaus ermöglicht Ihnen die Klasse, den Datensatz order_id abzurufen, den Sie gerade durch Zugriff auf die öffentliche Eigenschaft last_insert_id erstellt haben.

      Die Klasse DBTransaction ist nun bereit, von jedem PHP-Code, den Sie als Nächstes erstellen, aufgerufen und verwendet zu werden.

      Schritt 3 – Erstellen eines PHP-Skripts zur Verwendung der Klasse DBTransaction

      Sie erstellen ein PHP-Skript, das die Klasse DBTransaction implementiert und eine Gruppe von SQL-Befehlen in die MySQL-Datenbank sendet. Sie imitieren den Workflow einer Kundenbestellung in einem Online-Einkaufswagen.

      Diese SQL-Abfragen wirken sich auf die Tabellen orders und orders_products aus. Ihre Klasse DBTransaction sollte nur Änderungen in der Datenbank zulassen, wenn alle Abfragen fehlerfrei ausgeführt werden. Andernfalls erhalten Sie einen Fehler zurück, und alle Änderungsversuche werden rückgängig gemacht.

      Sie erstellen eine einzelne Bestellung für den mit customer_id 1 identifizierten Kunden JOHN DOE. Die Bestellung des Kunden enthält drei verschiedene Artikel mit unterschiedlichen Mengen aus der Tabelle products. Ihr PHP-Skript nimmt die Bestelldaten des Kunden und übergibt sie an die Klasse DBTransaction.

      Erstellen Sie die Datei orders.php:

      • sudo nano /var/www/html/orders.php

      Fügen Sie dann den folgenden Code in die Datei ein:

      /var/www/html/orders.php

      <?php
      
      require("DBTransaction.php");
      
      $db_host = "database_host";
      $db_name = "database_name";
      $db_user = "database_user";
      $db_password = "PASSWORD";
      
      $customer_id = 2;
      
      $products[] = [
        'product_id' => 1,
        'price' => 25.50,
        'quantity' => 1
      ];
      
      $products[] = [
        'product_id' => 2,
        'price' => 13.90,
        'quantity' => 3
      ];
      
      $products[] = [
        'product_id' => 3,
        'price' => 45.30,
        'quantity' => 2
      ];
      
      $transaction = new DBTransaction($db_host, $db_user, $db_password, $db_name);
      

      Sie haben ein PHP-Skript erstellt, das eine Instanz der Klasse DBTransaction initialisiert, die Sie in Schritt 2 erstellt haben.

      In diesem Skript fügen Sie die Datei DBTransaction.php ein und initialisieren die Klasse DBTransaction. Als Nächstes bereiten Sie ein mehrdimensionales Array aller Produkte vor, die der Kunde im Geschäft bestellt. Sie rufen auch die Methode startTransaction() auf, um eine Transaktion zu starten.

      Anschließend fügen Sie den folgenden Code hinzu, um Ihr Skript orders.php zu vervollständigen:

      /var/www/html/orders.php

      . . .
      $order_query = "insert into orders (order_id, customer_id, order_date, order_total) values(:order_id, :customer_id, :order_date, :order_total)";
      $product_query = "insert into orders_products (order_id, product_id, price, quantity) values(:order_id, :product_id, :price, :quantity)";
      
      $transaction->insertQuery($order_query, [
        'customer_id' => $customer_id,
        'order_date' => "2020-01-11",
        'order_total' => 157.8
      ]);
      
      $order_id = $transaction->last_insert_id;
      
      foreach ($products as $product) {
        $transaction->insertQuery($product_query, [
          'order_id' => $order_id,
          'product_id' => $product['product_id'],
          'price' => $product['price'],
          'quantity' => $product['quantity']
        ]);
      }
      
      $result = $transaction->submit();
      
      if ($result) {
          echo "Records successfully submitted";
      } else {
          echo "There was an error.";
      }
      
      

      Speichern und schließen Sie die Datei, indem Sie STRG + X, Y, dann ENTER drücken.

      Bereiten Sie den Befehl vor, der über die Methode insertTransaction in die Tabelle orders eingefügt werden soll. Danach rufen Sie den Wert der öffentlichen Eigenschaft last_insert_id aus der Klasse DBTransaction ab und verwenden ihn als $order_id.

      Sobald Sie über eine $order_id verfügen, verwenden Sie die eindeutige ID, um die von dem Kunden bestellten Artikel in die Tabelle orders_products einzufügen.

      Anschließend rufen Sie die Methode submitTransaction auf, um die gesamten Bestelldetails des Kunden in die Datenbank zu übertragen, wenn es keine Probleme gibt. Andernfalls macht die Methode submitTransaction die versuchten Änderungen rückgängig.

      Jetzt führen Sie das Skript orders.php in Ihrem Browser aus. Führen Sie das Folgende aus und ersetzen Sie your-server-IP mit der öffentlichen IP-Adresse Ihres Servers:

      http://your-server-IP/orders.php

      Sie erhalten eine Bestätigung, dass die Datensätze erfolgreich übermittelt wurden.

      PHP-Ausgabe aus der MySQL-Klasse Transactions

      Ihr PHP-Skript funktioniert wie erwartet und die Bestellung zusammen mit den zugehörigen Bestellprodukten wurde atomar in die Datenbank übertragen.

      Sie haben die Datei orders.php in einem Browserfenster ausgeführt. Das Skript hat die Klasse DBTransaction aufgerufen, die ihrerseits die Details der orders in die Datenbank übermittelte. Im nächsten Schritt überprüfen Sie, ob die Datensätze in den Bezugstabellen der Datenbank gespeichert wurden.

      Schritt 4 — Bestätigen der Einträge in Ihrer Datenbank

      In diesem Schritt überprüfen Sie, ob die vom Browserfenster aus initiierte Transaktion für die Bestellung des Kunden wie erwartet in die Datenbanktabellen verbucht wurde.

      Dazu melden Sie sich erneut bei Ihrer MySQL-Datenbank an:

      • sudo mysql -u sample_user -p

      Geben Sie das Passwort für den sample_user ein und drücken Sie ENTER, um fortzufahren.

      Wechseln Sie zur Datenbank sample_store:

      Stellen Sie sicher, dass die Datenbank geändert wird, bevor Sie fortfahren, indem Sie die folgende Ausgabe bestätigen:

      Output

      Database Changed.

      Geben Sie dann den folgenden Befehl ein, um Datensätze aus der Tabelle orders abzurufen:

      Dadurch wird die folgende Ausgabe angezeigt, die die Bestellung des Kunden beschreibt:

      Output

      +----------+---------------------+-------------+-------------+ | order_id | order_date | customer_id | order_total | +----------+---------------------+-------------+-------------+ | 1 | 2020-01-11 00:00:00 | 2 | 157.8 | +----------+---------------------+-------------+-------------+ 1 row in set (0.00 sec)

      Rufen Sie dann die Datensätze aus der Tabelle orders_products ab:

      • SELECT * FROM orders_products;

      Sie sehen eine Ausgabe ähnlich der folgenden mit einer Liste von Produkten aus der Bestellung des Kunden:

      Output

      +--------+----------+------------+-------+----------+ | ref_id | order_id | product_id | price | quantity | +--------+----------+------------+-------+----------+ | 1 | 1 | 1 | 25.5 | 1 | | 2 | 1 | 2 | 13.9 | 3 | | 3 | 1 | 3 | 45.3 | 2 | +--------+----------+------------+-------+----------+ 3 rows in set (0.00 sec)

      Die Ausgabe bestätigt, dass die Transaktion in der Datenbank gespeichert wurde und Ihre Helferklasse DBTransaction wie erwartet funktioniert.

      Zusammenfassung

      In diesem Leitfaden haben Sie die PHP PDO verwendet, um mit MySQL-Transaktionen zu arbeiten. Obwohl dies kein erschöpfender Artikel über die Gestaltung einer E-Commerce-Software ist, hat er ein Beispiel für die Verwendung von MySQL-Transaktionen in Ihren Anwendungen bereitgestellt.

      Weitere Informationen über das Modell MySQL ACID finden Sie in dem Leitfaden InnoDB und das ACID-Modell auf der offiziellen MySQL-Website. Besuchen Sie unsere MySQL-Inhaltsseite für weitere verwandte Tutorials, Artikel und Fragen und Antworten.



      Source link

      Verstehen der Standardparameter in JavaScript


      Der Autor hat den COVID-19 Relief Fund dazu ausgewählt, eine Spende im Rahmen des Programms Write for DOnations zu erhalten.

      Einführung

      In ECMAScript 2015 wurden Standardfunktionsparameter in die JavaScript-Sprache eingeführt. Diese ermöglichen Entwicklern, eine Funktion mit Standardwerten zu initialisieren, wenn dem Funktionsaufruf die Argumente nicht geliefert werden. Wenn Sie Funktionsparameter auf diese Weise initialisieren, werden Ihre Funktionen leichter lesbar und weniger fehleranfällig, und Sie erhalten ein Standardverhalten für Ihre Funktionen. Dies hilft Ihnen, Fehler zu vermeiden, die aus der Übergabe von undefined Argumenten und der Destrukturierung nicht vorhandener Objekte resultieren.

      In diesem Artikel werden Sie den Unterschied zwischen Parametern und Argumenten überprüfen, lernen, wie man Standardparameter in Funktionen verwendet, alternative Möglichkeiten zur Unterstützung von Standardparametern sehen und erfahren, welche Arten von Werten und Ausdrücken als Standardparameter verwendet werden können. Sie werden auch Beispiele durcharbeiten, die zeigen, wie Standardparameter in JavaScript funktionieren.

      Argumente und Parameter

      Bevor die Standardfunktionsparameter erklärt werden, ist es wichtig zu wissen, worauf Parameter standardmäßig eingestellt werden können. Aus diesem Grund werden wir zunächst den Unterschied zwischen Argumenten und Parametern in einer Funktion untersuchen. Wenn Sie mehr über diese Unterscheidung erfahren möchten, lesen Sie unseren früheren Artikel in der JavaScript-Reihe, Definieren von Funktionen in JavaScript.

      Im folgenden Codeblock erstellen Sie eine Funktion, die die Kubikzahl einer gegebenen Zahl, definiert als x, zurückgibt:

      // Define a function to cube a number
      function cube(x) {
        return x * x * x
      }
      

      Die Variable x in diesem Beispiel ist ein Parameter – eine benannte Variable, die an eine Funktion übergeben wird. Ein Parameter muss immer in einer Variable enthalten sein und darf niemals einen direkten Wert haben.

      Werfen Sie nun einen Blick auf diesen nächsten Codeblock, der die soeben erstellte Funktion cube anruft:

      // Invoke cube function
      cube(10)
      

      Dadurch erhalten Sie folgenden Output:

      Output

      1000

      In diesem Fall ist 10 ein Argument – ein Wert, der einer Funktion beim Aufrufen übergeben wird. Häufig wird der Wert auch in einer Variable enthalten sein, wie in diesem nächsten Beispiel:

      // Assign a number to a variable
      const number = 10
      
      // Invoke cube function
      cube(number)
      

      Dies führt zum gleichen Ergebnis:

      Output

      1000

      Wenn Sie ein Argument nicht an eine Funktion übergeben, die ein solches erwartet, wird die Funktion implizit als Wert undefined verwendet:

      // Invoke the cube function without passing an argument
      cube()
      

      Dies gibt zurück:

      Output

      NaN

      In diesem Fall versucht cube() den Wert von undefined * undefined * undefined zu berechnen, was zu NaN oder „Not a Number“, also „Keine Zahl“, führt. Weitere Informationen hierzu finden Sie in dem Abschnitt Verstehen von Datenarten in JavaScript.

      Dieses automatische Verhalten kann manchmal ein Problem darstellen. In einigen Fällen möchten Sie vielleicht, dass der Parameter einen Wert hat, auch wenn kein Argument an die Funktion übergeben wurde. Hier kommt die Standardparameter-Funktion ins Spiel, ein Thema, das Sie im nächsten Abschnitt behandeln werden.

      Syntax der Standardparameter

      Durch die Hinzufügung von Standardparametern in ES2015 können Sie nun jedem Parameter einen Standardwert zuweisen, den die Funktion beim Aufruf ohne Argument anstelle von undefined verwendet. Dieser Abschnitt zeigt Ihnen zunächst, wie Sie dies manuell tun, und führt Sie dann durch die Einstellung von Standardparametern.

      Ohne Standardparameter müssten Sie explizit auf undefined Werte prüfen, um Standardwerte zu setzen, wie in diesem Beispiel gezeigt:

      // Check for undefined manually
      function cube(x) {
        if (typeof x === 'undefined') {
          x = 5
        }
      
        return x * x * x
      }
      
      cube()
      

      Dabei wird mit Hilfe einer bedingten Anweisung geprüft, ob der Wert automatisch als undefined bereitgestellt wurde; dann wird der Wert von x auf 5 gesetzt. Dies führt zu der folgenden Ausgabe:

      Output

      125

      Im Gegensatz dazu wird durch die Verwendung von Standardparametern dasselbe Ziel mit wesentlich weniger Code erreicht. Sie können dem Parameter in cube einen Standardwert zuweisen, indem Sie ihm den Gleichheitszuweisungsoperator (=), wie hier hervorgehoben, zuweisen:

      // Define a cube function with a default value
      function cube(x = 5) {
        return x * x * x
      }
      

      Wenn die Funktion cube nun ohne Argument aufgerufen wird, weist sie 5 zu x zu und gibt anstelle von NaN die Berechnung zurück:

      // Invoke cube function without an argument
      cube()
      

      Output

      125

      Bei der Übergabe eines Arguments funktioniert sie weiterhin wie beabsichtigt, indem sie den Standardwert ignoriert:

      // Invoke cube function with an argument
      cube(2)
      

      Output

      8

      Ein wichtiger zu beachtender Vorbehalt ist jedoch, dass der Standardparameterwert auch eine explizite undefined Übergabe als Argument an eine Funktion überschreibt, wie hier gezeigt:

      // Invoke cube function with undefined
      cube(undefined)
      

      Dies ergibt die Berechnung mit x gleich 5:

      Output

      125

      In diesem Fall wurden die Standardparameterwerte berechnet und ein expliziter Wert undefined hat sie nicht überschrieben.

      Nachdem Sie nun eine Vorstellung von der grundlegenden Syntax von Standardparametern haben, zeigt der nächste Abschnitt, wie Standardparameter mit verschiedenen Datentypen funktionieren.

      Datentypen für Standardparameter

      Jeder primitive Wert oder jedes Objekt kann als Standardparameterwert verwendet werden. In diesem Abschnitt sehen Sie, wie diese Flexibilität die Möglichkeiten zur Verwendung von Standardparametern erhöht.

      Zuerst setzen Sie Parameter, indem Sie eine Zahl, Zeichenfolge, booleschen Wert, ein Objekt, ein Array und einen Nullwert als Standardwert verwenden. In diesem Beispiel wird die Syntax der Pfeilfunktion verwendet:

      // Create functions with a default value for each data type
      const defaultNumber = (number = 42) => console.log(number)
      const defaultString = (string = 'Shark') => console.log(string)
      const defaultBoolean = (boolean = true) => console.log(boolean)
      const defaultObject = (object = { id: 7 }) => console.log(object)
      const defaultArray = (array = [1, 2, 3]) => console.log(array)
      const defaultNull = (nullValue = null) => console.log(nullValue)
      

      Wenn diese Funktionen ohne Parameter aufgerufen werden, verwenden sie alle die Standardwerte:

      // Invoke each function
      defaultNumber()
      defaultString()
      defaultBoolean()
      defaultObject()
      defaultArray()
      defaultNull()
      

      Output

      42 "Shark" true {id: 7} (3) [1, 2, 3] null

      Beachten Sie, dass jedes in einem Standardparameter erzeugte Objekt bei jedem Aufruf der Funktion erzeugt wird. Einer der häufigsten Anwendungsfälle für Standardparameter ist die Verwendung dieses Verhaltens, um Werte aus einem Objekt zu erhalten. Wenn Sie versuchen, einen Wert aus einem nicht existierenden Objekt zu destrukturieren oder auf einen Wert zuzugreifen, wird ein Fehler ausgelöst. Wenn der Standardparameter jedoch ein leeres Objekt ist, gibt er Ihnen einfach undefined Werte aus, anstatt einen Fehler zu verursachen:

      // Define a settings function with a default object
      function settings(options = {}) {
        const { theme, debug } = options
      
        // Do something with settings
      }
      

      Dadurch wird der Fehler vermieden, der durch die Destrukturierung nicht existierender Objekte verursacht wird.

      Nachdem Sie nun gesehen haben, wie Standardparameter mit verschiedenen Datentypen arbeiten, erklärt der nächste Abschnitt, wie mehrere Standardparameter zusammenarbeiten können.

      Verwenden mehrerer Standardparameter

      Sie können in einer Funktion beliebig viele Standardparameter verwenden.  In diesem Abschnitt erfahren Sie, wie Sie dies tun und wie Sie damit das DOM in einem realen Beispiel manipulieren können.

      Zuerst deklarieren Sie eine Funktion sum() mit mehreren Standardparametern:

      // Define a function to add two values
      function sum(a = 1, b = 2) {
        return a + b
      }
      
      sum()
      

      Dies führt zu der folgenden Standardberechnung:

      Output

      3

      Zusätzlich kann der in einem Parameter verwendete Wert in jedem nachfolgenden Standardparameter von links nach rechts verwendet werden. Beispielsweise erstellt diese Funktion createUser ein Benutzerobjekt userObj als dritten Parameter, und die Funktion selbst gibt nur userObj mit den ersten beiden Parametern zurück:

      // Define a function to create a user object using parameters
      function createUser(name, rank, userObj = { name, rank }) {
        return userObj
      }
      
      // Create user
      const user = createUser('Jean-Luc Picard', 'Captain')
      

      Wenn Sie user hier aufrufen, erhalten Sie Folgendes:

      Output

      {name: "Jean-Luc Picard", rank: "Captain"}

      Es wird normalerweise empfohlen, alle Standardparameter an das Ende einer Parameterliste zu setzen, sodass Sie optionale Werte einfach weglassen können. Wenn Sie einen Standardparameter zuerst verwenden, müssen Sie undefined explizit übergeben, um den Standardwert zu verwenden.

      Hier ist ein Beispiel mit dem Standardparameter am Anfang der Liste:

      // Define a function with a default parameter at the start of the list
      function defaultFirst(a = 1, b) {
        return a + b
      }
      

      Wenn Sie diese Funktion aufrufen, müssten Sie defaultFirst() mit zwei Argumenten aufrufen:

      defaultFirst(undefined, 2)
      

      Dies würde Folgendes ergeben:

      Output

      3

      Hier ist ein Beispiel mit dem Standardparameter am Ende der Liste:

      // Define a function with a default parameter at the end of the list
      function defaultLast(a, b = 1) {
        return a + b
      }
      
      defaultLast(2)
      

      Dies würde den gleichen Wert ergeben:

      Output

      3

      Beide Funktionen haben das gleiche Ergebnis, aber diejenige mit dem Standardwert am Ende ermöglicht einen wesentlich saubereren Funktionsaufruf.

      Für ein Beispiel aus der realen Welt ist hier eine Funktion, die ein DOM-Element erstellt und ein Text-Label und Klassen, falls vorhanden, hinzufügt.

      // Define function to create an element
      function createNewElement(tag, text, classNames = []) {
        const el = document.createElement(tag)
        el.textContent = text
      
        classNames.forEach(className => {
          el.classList.add(className)
        })
      
        return el
      }
      

      Sie können die Funktion mit einigen Klassen in einem Array aufrufen:

      const greeting = createNewElement('p', 'Hello!', ['greeting', 'active'])
      

      Der Aufruf von greeting ergibt den folgenden Wert:

      Output

      <p class="greeting active">Hello!</p>

      Wenn Sie jedoch das Array classNames aus dem Funktionsaufruf herauslassen, funktioniert die Funktion immer noch.

      const greeting2 = createNewElement('p', 'Hello!')
      

      greeting2 hat nun den folgenden Wert:

      Output

      <p>Hello!</p>

      In diesem Beispiel kann forEach() auf ein leeres Array ohne Ausgabe angewendet werden. Wenn dieses leere Array nicht im Standardparameter festgelegt wäre, würden Sie den folgenden Fehler erhalten:

      Output

      VM2673:5 Uncaught TypeError: Cannot read property 'forEach' of undefined at createNewElement (<anonymous>:5:14) at <anonymous>:12:18

      Nachdem Sie nun gesehen haben, wie mehrere Standardparameter zusammenwirken können, können Sie mit dem nächsten Abschnitt fortfahren, um zu sehen, wie Funktionsaufrufe als Standardparameter funktionieren.

      Funktionsaufrufe als Standardparameter

      Zusätzlich zu den Primitiven und Objekten kann das Ergebnis des Aufrufs einer Funktion als Standardparameter verwendet werden.

      In diesem Codeblock erstellen Sie eine Funktion, die eine Zufallszahl zurückgibt und verwenden dann das Ergebnis als Standardparameterwert in einer Funktion cube:

      // Define a function to return a random number from 1 to 10
      function getRandomNumber() {
        return Math.floor(Math.random() * 10)
      }
      
      // Use the random number function as a default parameter for the cube function
      function cube(x = getRandomNumber()) {
        return x * x * x
      }
      

      Wenn Sie nun die Funktion cube ohne Parameter aufrufen, hat jeder Aufruf der Funktion potenziell unterschiedliche Ergebnisse:

      // Invoke cube function twice for two potentially different results
      cube()
      cube()
      

      Die Ausgabe dieser Funktionsaufrufe wird variieren:

      Output

      512 64

      Sie können sogar integrierte Methoden verwenden, wie beispielsweise die des Objekts Math, und den in einem Funktionsaufruf zurückgegebenen Wert als Parameter in einer anderen Funktion verwenden.

      Im folgenden Beispiel wird x eine Zufallszahl zugewiesen, die als Parameter in der von Ihnen erstellten Funktion cube verwendet wird. Der Parameter y berechnet dann die Würfelwurzel der Zahl und überprüft, ob x und y gleich sind:

      // Assign a random number to x
      // Assign the cube root of the result of the cube function and x to y
      function doesXEqualY(x = getRandomNumber(), y = Math.cbrt(cube(x))) {
        return x === y
      }
      
      doesXEqualY()
      

      Dadurch ergibt sich Folgendes:

      Output

      true

      Ein Standardparameter kann sogar, wie in diesem Beispiel, eine Funktionsdefinition sein, die einen Parameter als innere Funktion definiert und den Funktionsaufruf von parameter zurückgibt:

      // Define a function with a default parameter that is an anonymous function
      function outer(
        parameter = function inner() {
          return 100
        }
      ) {
        return parameter()
      }
      
      // Invoke outer function
      outer()
      

      Output

      100

      Die Funktion inner wird bei jedem Aufruf der Funktion outer von Grund auf neu erzeugt.

      Zusammenfassung

      In diesem Artikel haben Sie gelernt, was Standardfunktionsparameter sind und wie sie verwendet werden.  Jetzt können Sie Standardparameter verwenden, um Ihre Funktionen sauber und leicht lesbar zu halten. Sie können Parametern auch im Voraus leere Objekte und Arrays zuweisen, um sowohl die Komplexität als auch die Codezeilen zu reduzieren, wenn es um Situationen wie das Abrufen von Werten aus einem Objekt oder das Durchschleifen eines Arrays geht.

      Wenn Sie mehr über JavaScript erfahren möchten, besuchen Sie die Homepage für unsere Reihe Codieren in JavaScript oder durchsuchen Sie unsere Reihe Codieren in Node.js für Artikel über Back-End-Entwicklung.



      Source link

      Anzeigen von Daten aus der DigitalOcean-API mit Django


      Der Autor hat die Mozilla Foundation dazu ausgewählt, im Rahmen des Programms Write for DOnations eine Spende zu erhalten.

      Einführung

      Da der Bedarf nach einer Full-Stack-Entwicklung weiter wächst, sorgen Web-Frameworks für Entwicklungsabläufe, die einfacher und effizienter sind; Django ist eines dieser Frameworks. Django kommt bei bekannten Websites wie Mozilla, Pinterest und Instagram zum Einsatz. Im Gegensatz zu Flask, das ein neutrales Mikro-Framework ist, enthält das Django PyPI-Paket alles, was Sie zur Full-Stack-Entwicklung benötigen; eine Datenbank oder Kontrolltafel für die Entwicklung muss nicht eingerichtet werden.

      Ein verbreitetes Anwendungsbeispiel für Django besteht in der Anzeige von Informationen aus APIs (wie Instagram-Posts oder GitHub-Repositorys) in Ihren eigenen Websites und Web-Apps. Zwar ist dies auch mit anderen Frameworks möglich, doch bedeutet das Motto “Batterien inbegriffen” von Django, dass der Aufwand geringer ist und weniger Pakete benötigt werden, um dasselbe Ergebnis zu erzielen.

      In diesem Tutorial erstellen Sie ein Django-Projekt, das die Droplet-Informationen Ihres DigitalOcean-Kontos mit der DigitalOcean v2 API anzeigt. Genauer gesagt werden Sie eine Website erstellen, die eine Tabelle mit Droplets anzeigt, in der ihre jeweiligen IP-Adressen, IDs, Hosting-Regionen und Ressourcen aufgeführt werden. Ihre Website wird BulmaCSS verwenden, um die Seite so zu gestalten, dass Sie sich auf die Entwicklung konzentrieren können und die Seite am Ende trotzdem gut aussieht.

      Nach Abschluss dieses Tutorials werden Sie über ein Django-Projekt verfügen, das eine Webseite erstellen kann, die wie folgt aussieht:

      Vorlage mit Tabelle von Droplet-Daten

      Voraussetzungen

      Bevor Sie diese Anleitung beginnen, benötigen Sie Folgendes:

      • Ein DigitalOcean-Konto mit mindestens einem Droplet und einem persönlichen Zugriffstoken. Stellen Sie sicher, dass Sie das Token an einem sicheren Ort aufbewahren; Sie werden es später in dem Tutorial noch benötigen.
      • Vertrautheit mit dem Richten von Anfragen an APIs. Ein umfassendes Tutorial zur Arbeit mit APIs finden Sie unter Verwenden von Web-APIs in Python3.
      • Eine lokale virtuelle Umgebung für Python zur Aufrechterhaltung von Abhängigkeiten. In diesem Tutorial verwenden wir den Namen do_django_api für unser Projektverzeichnis und env für unsere virtuelle Umgebung.
      • Vertrautheit mit der Vorlagenlogik von Django beim Rendern von Seiten mit API-Daten.
      • Vertrautheit mit der Anzeigelogik von Django bei der Handhabung von Daten, die von der API empfangen werden, und Übergabe an eine Vorlage für das Rendering.

      Schritt 1 — Einrichten eines einfachen Django-Projekts

      Installieren Sie Django aus der virtuellen Umgebung env heraus:

      Jetzt können Sie ein Django-Projekt starten und einige anfängliche Einrichtungsbefehle ausführen.

      Verwenden Sie django-admin startproject <name>, um im Projektordner, der den Namen Ihres Django-Projekts trägt, ein Unterverzeichnis zu erstellen; wechseln Sie anschließend in dieses Verzeichnis.

      • django-admin startproject do_django_project
      • cd do_django_project

      Nach der Erstellung finden Sie in diesem Unterverzeichnis manage.py; das ist die übliche Methode, um mit Django zu interagieren und Ihr Projekt auszuführen. Verwenden Sie migrate, um die Entwicklungsdatenbank von Django zu aktualisieren:

      • python3 manage.py migrate

      Sie werden eine Ausgabe sehen, die folgendermaßen aussieht, während die Datenbank aktualisiert wird:

      Output

      Operations to perform: Apply all migrations: admin, auth, contenttypes, sessions Running migrations: Applying contenttypes.0001_initial... OK Applying auth.0001_initial... OK Applying admin.0001_initial... OK Applying admin.0002_logentry_remove_auto_add... OK Applying admin.0003_logentry_add_action_flag_choices... OK Applying contenttypes.0002_remove_content_type_name... OK Applying auth.0002_alter_permission_name_max_length... OK Applying auth.0003_alter_user_email_max_length... OK Applying auth.0004_alter_user_username_opts... OK Applying auth.0005_alter_user_last_login_null... OK Applying auth.0006_require_contenttypes_0002... OK Applying auth.0007_alter_validators_add_error_messages... OK Applying auth.0008_alter_user_username_max_length... OK Applying auth.0009_alter_user_last_name_max_length... OK Applying auth.0010_alter_group_name_max_length... OK Applying auth.0011_update_proxy_permissions... OK Applying sessions.0001_initial... OK

      Verwenden Sie als Nächstes den Befehl runserver, um das Projekt auszuführen, damit Sie es testen können:

      • python3 manage.py runserver

      Die Ausgabe sieht wie folgt aus, während der Server gestartet wird:

      Output

      Watching for file changes with StatReloader Performing system checks... System check identified no issues (0 silenced). September 22, 2019 - 22:57:07 Django version 2.2.5, using settings 'do_django_project.settings' Starting development server at http://127.0.0.1:8000/ Quit the server with CONTROL-C.

      Sie verfügen nun über ein einfaches Django-Projekt und einen Entwicklungsserver, der ausgeführt wird. Um Ihren ausgeführten Entwicklungsserver anzuzeigen, rufen Sie in einem Browser 127.0.0.1:8000 auf. Damit wird die Startseite von Django angezeigt:

      Allgemeine Django-Startseite

      Als Nächstes erstellen Sie eine Django-App und konfigurieren Ihr Projekt, um eine Ansicht von dieser App auszuführen, damit Sie etwas Aufregenderes als die Standardseite sehen.

      Schritt 2 — Einrichten einer einfachen Django-App

      In diesem Schritt schaffen Sie das Fundament für die App, die Ihre Droplet-Ergebnisse enthalten wird. Sie werden später wieder zu dieser App zurückkehren, sobald Sie den API-Aufruf eingerichtet haben, um die App mit Daten zu füllen.

      Stellen Sie sicher, dass Sie sich im Verzeichnis do_django_project befinden, und erstellen Sie mit dem folgenden Befehl eine Django-App:

      • python3 manage.py startapp display_droplets

      Jetzt müssen Sie die neue App INSTALLED_APPS in der Datei settings.py hinzufügen, damit Django sie erkennen kann. settings.py ist eine Django-Konfigurationsdatei, die sich im Django-Projekt in einem anderen Unterverzeichnis befindet und den gleichen Namen trägt wie der Projektordner (do_django_project). Django hat beide Ordner für Sie erstellt. Wechseln Sie zum Verzeichnis do_django_project:

      Bearbeiten Sie settings.py in einem Editor Ihrer Wahl:

      Fügen Sie Ihre neue App dem Abschnitt INSTALLED_APPS der Datei hinzu:

      do_django_api/do_django_project/do_django_project/settings.py

      INSTALLED_APPS = [
          'django.contrib.admin',
          'django.contrib.auth',
          'django.contrib.contenttypes',
          'django.contrib.sessions',
          'django.contrib.messages',
          'django.contrib.staticfiles',
          # The new app
          'display_droplets',
      ]
      

      Speichern und schließen Sie die Datei, wenn Sie fertig sind.

      Anzeigefunktion GetDroplets

      Als Nächstes erstellen Sie eine Funktion namens GetDroplets in der Datei views.py der App display_droplets. Diese Funktion rendert die Vorlage,die Sie zur Anzeige von Droplet-Daten verwenden werden, als context von der API. context ist ein Wörterbuch, das es erlaubt, Daten aus Python-Code zu übernehmen und an eine HTML-Vorlage zu senden, damit sie sich in einer Webseite anzeigen lassen.

      Wechseln Sie zum Verzeichnis display_droplets:

      • cd ..
      • cd display_droplets

      Öffnen Sie views.py, um die Datei zu bearbeiten:

      Fügen Sie den folgenden Code zur Datei hinzu:

      do_django_api/do_django_project/display_droplets/views.py

      from django.views.generic import TemplateView
      
      class GetDroplets(TemplateView):
          template_name = 'droplets.html'
          def get_context_data(self, *args, **kwargs):
              pass
      

      Speichern und schließen Sie die Datei.

      Später werden Sie diese Funktion ausfüllen und die Datei droplets.html erstellen. Zuerst konfigurieren wir aber urls.py, um diese Funktion anzurufen, wenn Sie das Stammverzeichnis des Entwicklungsservers (127.0.0.1:8000) aufrufen.

      Wechseln Sie wieder zum Verzeichnis do_django_project:

      • cd ..
      • cd do_django_project

      Öffnen Sie urls.py, um die Datei zu bearbeiten:

      Fügen Sie eine import-Anweisung für GetDroplets und dann einen zusätzlichen Pfad zu urlpatterns hinzu, der auf die neue Ansicht verweist.

      do_django_api/do_django_project/do_django_project/urls.py

      from django.contrib import admin
      from django.urls import path
      from display_droplets.views import GetDroplets
      
      urlpatterns = [
          path('admin/', admin.site.urls),
          path('', GetDroplets.as_view(template_name='droplets.html'), name='Droplet View'),
      ]
      

      Wenn Sie Ihre eigenen Pfade einrichten möchten, ist der erste Parameter die URL (wie z. B. example.com/**admin**), der zweite Parameter die Funktion, die zum Erstellen der Webseite aufgerufen wird, und der dritte nur ein Name für den Pfad.

      Speichern und schließen Sie die Datei.

      Droplets-Vorlage

      Als Nächstes arbeiten Sie mit Vorlagen. Vorlagen sind HTML-Dateien, die Django zur Erstellung von Webseiten verwendet. In diesem Fall verwenden Sie eine Vorlage, um eine HTML-Seite zu erstellen, die die API-Daten anzeigt.

      Wechseln Sie wieder zum Verzeichnis display_droplets:

      • cd ..
      • cd display_droplets

      Erstellen Sie in diesem Verzeichnis einen Ordner template und wechseln Sie in dieses Verzeichnis:

      • mkdir templates
      • cd templates

      Erstellen Sie droplets.html und öffnen Sie die Datei, um sie zu bearbeiten:

      Um kein CSS für dieses Projekt schreiben zu müssen, verwenden wir Bulma CSS, da es sich dabei um ein kostenloses und schlankes CSS-Framework für die Erstellung von übersichtlichen Webseiten handelt. Sie müssen der HTML lediglich einige Klassenattribute hinzufügen.

      Jetzt erstellen wir eine Vorlage mit einer einfachen Navigationsleiste. Fügen Sie der Datei droplets.html den folgenden Code hinzu:

      do_django_api/do_django_project/display_droplets/templates/droplets.html

      <!DOCTYPE html>
      <html lang="en">
      <head>
          <meta charset="UTF-8">
          <title>DigitalOcean Droplets</title>
          <link crossorigin="anonymous"
                href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.7.4/css/bulma.min.css"
                integrity="sha256-8B1OaG0zT7uYA572S2xOxWACq9NXYPQ+U5kHPV1bJN4="
                rel="stylesheet"/>
          <link rel="shortcut icon" type="image/png" href="https://assets.digitalocean.com/logos/favicon.png"/>
      </head>
      <body>
      <nav aria-label="main navigation" class="navbar is-light" role="navigation">
          <div class="navbar-brand">
              <div class="navbar-item">
                  <img atl="DigitalOcean" src="https://assets.digitalocean.com/logos/DO_Logo_icon_blue.png"
                       style="margin-right: 0.5em;">Droplets
              </div>
          </div>
      </nav>
      </body>
      </html>
      

      Speichern und schließen Sie die Datei.

      Dieser Code sorgt dafür, dass Bulma in den HTML-Baustein importiert und eine nav-Leiste zur Anzeige von “Droplets” erstellt wird.

      Aktualisieren Sie Ihren Browser-Tab, um die Änderungen, die Sie an der Vorlage vorgenommen haben, anzuzeigen.

      Vorlage mit einfacher Kopfzeile

      Bisher haben Sie noch keine APIs verwendet; Sie haben vielmehr ein Fundament für das Projekt geschaffen. Als Nächstes nutzen Sie diese Seite sinnvoll, indem Sie einen API-Aufruf einrichten und die Droplet-Daten bereitstellen.

      Schritt 3 — Einrichten des API-Aufrufs

      In diesem Schritt richten Sie einen API-Aufruf ein und senden die Droplet-Daten als Kontext an die Vorlage, um in einer Tabelle angezeigt zu werden.

      Abrufen von Droplet-Daten

      Navigieren Sie zurück zum App-Verzeichnis display_droplets:

      Installieren Sie die Bibliothek requests, damit Sie mit der API kommunizieren können:

      Mithilfe der Bibliothek requests kann Ihr Code Daten von APIs anfordern und Kopfzeilen hinzufügen (zusätzliche Daten, die mit unserer Anfrage gesendet werden).

      Als Nächstes erstellen Sie eine Datei services.py, über die Sie den API-Aufruf vornehmen. Diese Funktion verwendet requests, um mit https://api.digitalocean.com/v2/droplets zu kommunizieren und jedes Droplet in der JSON-Datei anzufügen, das an eine Liste zurückgegeben wird.

      Öffnen Sie services.py, um die Datei zu bearbeiten:

      Fügen Sie den folgenden Code zur Datei hinzu:

      do_django_api/do_django_project/display_droplets/services.py

      import os
      import requests
      
      def get_droplets():
          url = 'https://api.digitalocean.com/v2/droplets'
          r = requests.get(url, headers={'Authorization':'Bearer %s' % 'access_token'})
          droplets = r.json()
          droplet_list = []
          for i in range(len(droplets['droplets'])):
              droplet_list.append(droplets['droplets'][i])
          return droplet_list
      

      Innerhalb der Funktion get_droplets passieren zwei Dinge: Es wird eine Anfrage vorgenommen und Daten werden analysiert. url enthält die URL, die Droplet-Daten von der DigitalOcean-API anfordert. r speichert die angeforderten Daten.

      requests übernimmt in diesem Fall zwei Parameter: url und headers. Wenn Sie Daten von einer anderen API nutzen möchten, ersetzen Sie den Wert url durch die entsprechende URL. headers sendet DigitalOcean Ihr Zugriffstoken, damit das Unternehmen weiß, dass Sie die Anfrage vornehmen dürfen und für welches Konto die Anfrage vorgenommen wird.

      droplets enthält die Informationen aus der Variable r, wurde nun jedoch von JSON, dem Format, in dem die API Informationen sendet, in ein Wörterbuch konvertiert, das bequem in einer for-Schleife zu verwenden ist.

      Die nächsten drei Zeilen erstellen ein Array namens droplet_list[]. Dann iteriert eine for-Schleife über die Informationen in droplets und fügt jedes Element der Liste hinzu. Alle von der API übernommenen und in droplets gespeicherten Informationen finden Sie in der Entwicklerdokumentation von DigitalOcean.

      Anmerkung: Vergessen Sie nicht, access_token durch Ihr Zugriffstoken zu ersetzen. Bewahren Sie das Token außerdem sicher auf und veröffentlichen Sie es niemals online.

      Speichern und schließen Sie die Datei.

      Schutz Ihres Zugriffstokens

      Sie sollten Ihr Zugriffstoken stets verstecken. Wenn aber auch andere Personen das Projekt ausführen dürfen, sollten Sie ihnen eine einfache Möglichkeit bieten, um eigene Zugriffstoken hinzuzufügen, ohne dass Python-Code bearbeitet werden muss. DotENV ist die Lösung, wenn Variablen in einer .env-Datei aufbewahrt werden, die bequem bearbeitet werden kann.

      Wechseln Sie wieder zum Verzeichnis do_django_project:

      Um mit Umgebungsvariablen zu arbeiten, installieren Sie python-dotenv:

      • pip install python-dotenv

      Nach der Installation müssen Sie Django für den Umgang mit Umgebungsvariablen konfigurieren, damit Sie in Code auf sie verweisen können. Dazu müssen Sie einige Codezeilen zu manage.py und wsgi.py hinzufügen.

      Öffnen Sie manage.py, um die Datei zu bearbeiten:

      Fügen Sie folgenden Code hinzu:

      do_django_api/do_django_project/manage.py

      
      """Django's command-line utility for administrative tasks."""
      import os
      import sys
      import dotenv
      
      def main():
          os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'do_django_project.settings')
          try:
              from django.core.management import execute_from_command_line
          except ImportError as exc:
              raise ImportError(
                  "Couldn't import Django. Are you sure it's installed and "
                  "available on your PYTHONPATH environment variable? Did you "
                  "forget to activate a virtual environment?"
              ) from exc
          execute_from_command_line(sys.argv)
      
      if __name__ == '__main__':
          main()
      
      dotenv.load_dotenv(
          os.path.join(os.path.dirname(__file__), '.env')
      )
      

      Das Hinzufügen von dem Code in manage.py bedeutet, dass bei der Ausgabe von Befehlen an Django in der Entwicklung Umgebungsvariablen von Ihrer .env-Datei verarbeitet werden.

      Speichern und schließen Sie die Datei.

      Wenn Sie in Ihren Produktionsprojekten Umgebungsvariablen bearbeiten müssen, können Sie dies mit der Datei wsgi.py tun. Wechseln Sie zum Verzeichnis do_django_project:

      Öffnen Sie anschließend wsgi.py, um die Datei zu bearbeiten:

      Fügen Sie wsgi.py folgenden Code hinzu:

      do_django_api/do_django_project/do_django_project/wsgi.py

      
      import os
      import dotenv
      
      from django.core.wsgi import get_wsgi_application
      
      os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'do_django_project.settings')
      
      dotenv.load_dotenv(
          os.path.join(os.path.dirname(os.path.dirname(__file__)), '.env')
      )
      
      application = get_wsgi_application()
      

      Dieser Codeausschnitt weist einen zusätzlichen os.path.dirname() auf, weil wsgi.py zwei Verzeichnisse zurückgehen muss, um die Datei .env zu finden. Dieser Ausschnitt ist nicht identisch mit dem, der für manage.py verwendet wird.

      Speichern und schließen Sie die Datei.

      Nun können Sie anstelle Ihres Zugriffstokens eine Umgebungsvariable in services.py verwenden. Wechseln Sie wieder zum Verzeichnis display_droplets:

      • cd ..
      • cd display_droplets

      Öffnen Sie services.py, um die Datei zu bearbeiten:

      Ersetzen Sie nun Ihr Zugriffstoken durch eine Umgebungsvariable:

      do_django_api/display_droplets/services.py

      import os
      import requests
      
      def get_droplets():
          url = "https://api.digitalocean.com/v2/droplets"
          r = requests.get(url, headers={'Authorization':'Bearer %s' % os.getenv('DO_ACCESS_TOKEN')})
          droplets = r.json()
          droplet_list = []
          for i in range(len(droplets['droplets'])):
              droplet_list.append(droplets['droplets'][i])
          return droplet_list
      

      Speichern und schließen Sie die Datei.

      Der nächste Schritt besteht aus der Erstellung einer .env-Datei. Wechseln Sie wieder zum Verzeichnis do_django_project:

      Erstellen Sie eine .env-Datei und öffnen Sie die Datei, um sie zu bearbeiten:

      Fügen Sie in .env Ihr Token als Variable DO_ACCESS_TOKEN hinzu:

      do_django_api/do_django_project/.env

      DO_ACCESS_TOKEN=access_token
      

      Speichern und schließen Sie die Datei.

      Anmerkung: Fügen Sie .env zu Ihrer .gitignore-Datei hinzu, damit sie nie in Ihren Commits enthalten ist.

      Die API-Verbindung ist nun eingerichtet und konfiguriert; zudem haben Sie Ihr Zugriffstoken geschützt. Es ist an der Zeit, die Informationen, die Sie für den Benutzer abgerufen haben, bereitzustellen.

      Schritt 4 — Umgang mit Droplet-Daten in Ansichten und Vorlagen

      Nachdem Sie nun API-Aufrufe vornehmen können, müssen Sie die Droplet-Daten zum Rendern an die Vorlage senden. Kehren wir zum Stub der Funktion GetDroplets zurück, die Sie zuvor in views.py erstellt haben. In der Funktion senden Sie droplet_list als Kontext an die Vorlage droplets.html.

      Wechseln Sie zum Verzeichnis display_droplets:

      Öffnen Sie views.py, um die Datei zu bearbeiten:

      Fügen Sie views.py folgenden Code hinzu:

      do_django_api/do_django_project/display_droplets/views.py

      from django.shortcuts import render
      from django.views.generic import TemplateView
      from .services import get_droplets
      
      class GetDroplets(TemplateView):
          template_name = 'droplets.html'
          def get_context_data(self, *args, **kwargs):
              context = {
                  'droplets' : get_droplets(),
              }
              return context
      

      Die an die Vorlage droplets.html gesendeten Informationen werden mit dem Wörterbuch context verwaltet. Aus diesem Grund dient droplets als Schlüssel, während das von get_droplets() zurückgegebene Array als Wert fungiert.

      Speichern und schließen Sie die Datei.

      Bereitstellen der Daten in der Vorlage

      In der Vorlage droplets.html erstellen Sie eine Tabelle und befüllen sie mit den Droplet-Daten.

      Wechseln Sie zum Verzeichnis templates:

      Öffnen Sie droplets.html, um die Datei zu bearbeiten:

      Fügen Sie nach dem Element nav in droplets.html folgenden Code hinzu:

      do_django_api/do_django_project/display_droplets/templates/droplets.html

      <table class="table is-fullwidth is-striped is-bordered">
          <thead>
          <tr>
              <th>Name</th>
              <th>IPv4 Address(es)</th>
              <th>Id</th>
              <th>Region</th>
              <th>Memory</th>
              <th>CPUs</th>
              <th>Disk Size</th>
          </tr>
          </thead>
          <tbody>
          {% for droplet in droplets %}
          <tr>
              <th>{{ droplet.name }}</th>
              {% for ip in droplet.networks.v4 %}
              <td>{{ ip.ip_address }}</td>
              {% endfor %}
              <td>{{ droplet.id }}</td>
              <td>{{ droplet.region.name }}</td>
              <td>{{ droplet.memory }}</td>
              <td>{{ droplet.vcpus }}</td>
              <td>{{ droplet.disk }}</td>
          </tr>
          {% endfor %}
          </tbody>
      </table>
      

      {% for droplet in droplets %} ... {% endfor %} ist eine Schleife, die durch das Array von Droplets, die aus views.py abgerufen wurden, iteriert. Jedes Droplet wird in eine Tabellenzeile eingefügt. Die verschiedenen {{ droplet.<attribute> }}-Zeilen rufen dieses Attribut für jedes Droplet in der Schleife ab und fügen es in eine Tabellenzelle ein.

      Speichern und schließen Sie die Datei.

      Aktualisieren Sie Ihren Browser; es wird eine Liste von Droplets angezeigt.

      Vorlage mit Tabelle an Droplet-Daten

      Nun können Sie die DigitalOcean-API in Ihren Django-Projekten verwenden. Sie haben die von der API abgerufenen Daten übernommen und in die zuvor erstellte Vorlage eingespeist, um die Informationen auf lesbare und flexible Weise anzuzeigen.

      Zusammenfassung

      In diesem Artikel haben Sie ein Django-Projekt erstellt, das Droplet-Daten aus der DigitalOcean-API im Bulma CSS-Stil anzeigen kann. In diesem Tutorial haben Sie drei wichtige Fähigkeiten erlernt:

      • Verwalten von API-Anfragen in Python mit den Modulen requests und json.
      • Anzeigen von API-Daten in einem Django-Projekt unter Verwendung der Logiken view und template.
      • Sicheres Verwalten Ihrer API-Token in Django mit dotenv.

      Nachdem Sie eine Einführung in die Handhabung von APIs in Django erhalten haben, können Sie nun ein eigenes Projekt erstellen: entweder mit einer anderen Funktion aus der DigitalOcean-API oder einer ganz anderen API. Zudem können Sie andere Django-Tutorials bzw. ein ähnliches Tutorial mit dem React-Framework konsultieren.





      Source link