One place for hosting & domains

      данных

      Использование типа данных MySQL BLOB для хранения изображений с PHP в Ubuntu 18.04


      Автор выбрал Girls Who Code для получения пожертвования в рамках программы Write for DOnations.

      Введение

      Большие двоичные объекты (BLOB) — это тип данных MySQL для хранения двоичных данных, таких как изображения, мультимедийные файлы и файлы PDF.

      При создании приложений, для которых требуются тесно связанные базы данных, где изображения нужно синхронизировать с другими данными (например, портал сотрудников, база данных студентов или финансовое приложение), будет полезно хранить изображения, например, фотографии паспортов и подписей студентов, в базе данных MySQL вместе с другой связанной информацией.

      Для этой цели будет полезен тип данных MySQL BLOB. Такой подход к программированию устраняет необходимость создания отдельной файловой системы для хранения изображений. Такая схема также обеспечивает централизацию базы данных, делая ее более портативной и безопасной за счет изоляции данных от файловой системы. Создавать резервные копии также будет проще, поскольку для этого достаточно будет создать один файл дампа MySQL, где будут храниться все ваши данные.

      Получение данных также ускорится, и при создании записей вы можете быть уверены в соблюдении правил проверки данных и целостности ссылок, особенно при использовании транзакций MySQL.

      В этом обучающем модуле мы используем тип данных MySQL BLOB для сохранения изображений в коде PHP в Ubuntu 18.04.

      Предварительные требования

      Для выполнения этого обучающего модуля вам потребуется следующее:

      Шаг 1 — Создание базы данных

      Для начала создайте тестовую базу данных для своего проекта. Для этого подключитесь к серверу через SSH и запустите следующую команду для входа на сервер MySQL с привилегиями root:

      Введите пароль пользователя root для вашей базы данных MySQL и нажмите ENTER, чтобы продолжить.

      Затем запустите следующую команду для создания базы данных. В этом обучающем модуле мы назовем базу данных test_company:

      • CREATE DATABASE test_company;

      После создания базы данных вы увидите следующее:

      Output

      Query OK, 1 row affected (0.01 sec)

      Затем создайте учетную запись test_user на сервере MySQL и обязательно замените PASSWORD на надежный пароль:

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

      Вывод должен выглядеть так:

      Output

      Query OK, 0 rows affected (0.01 sec)

      Чтобы предоставить пользователю test_user полные права доступа к базе данных test_company, выполните команду:

      • GRANT ALL PRIVILEGES ON test_company.* TO 'test_user'@'localhost';

      Вы должны увидеть следующее:

      Output

      Query OK, 0 rows affected (0.01 sec)

      Очистите таблицу прав доступа, чтобы СУБД MySQL перезагрузила разрешения:

      На экран должно быть выведено следующее:

      Output

      Query OK, 0 rows affected (0.01 sec)

      Мы подготовили базу данных test_company и пользователя test_user. Теперь мы можем перейти к созданию таблицы products для сохранения образцов продуктов. Позднее мы используем эту таблицу для вставки и получения записей, чтобы продемонстрировать работу объектов MySQL BLOB.

      Выполните выход из сервера MySQL:

      Снова войдите в систему под учетными данными созданного пользователя test_user:

      Введите в диалоге пароль пользователя test_user и нажмите ENTER, чтобы продолжить. Переключитесь на базу данных test_company с помощью следующей команды:

      После выбора базы данных test_company MySQL выведет на экран следующее:

      Output

      Database changed

      Затем создайте таблицу products, запустив команду:

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

      Эта команда создает таблицу с именем products. В таблице имеется четыре столбца:

      • product_id: в этом столбце используется тип данных BIGINT, за счет чего обеспечивается поддержка больших списков продуктов, где может содержаться до 2⁶³-1 элементов. Вы пометили столбец как PRIMARY KEY для уникальной идентификации продуктов. Чтобы MySQL обрабатывала генерирование новых идентификаторов для вставленных столбцов, вы использовали ключевое слово AUTO_INCREMENT.

      • product_name: в этом столбце хранятся названия продуктов. Мы использовали тип данных VARCHAR, поскольку это поле обычно обрабатывает не более 50 бувенно-числовых символов. Предел в 50 символов — это гипотетическое значение, используемое для целей этого обучающего модуля.

      • price: для демонстрационных целей мы добавили в таблицу products столбец price для хранения информации о розничной цене продуктов. Поскольку некоторые продукты могут иметь значения с плавающей запятой (например, 23.69, 45.36, 102.99), мы использовали тип данных DOUBLE.

      • product_image: в этом столбце данные типа BLOB используются для хранения двоичных данных изображений продуктов.

      Мы использовали для таблицы InnoDB, СИСТЕМУ ХРАНЕНИЯ, поддерживающую широкий набор функций, включая транзакции MySQL. После выполнения этой команды для создания таблицы products вы увидите на экране следующее:

      Output

      Query OK, 0 rows affected (0.03 sec)

      Выполните выход с сервера MySQL:

      Вы увидите следующее

      Output

      Bye

      Теперь таблица products готова для хранения записей, в том числе изображений продуктов, и на следующем шаге мы заполним ее продуктами.

      Шаг 2 — Создание скриптов PHP для подключения к базе данных и ее заполнения

      На этом шаге мы создадим скрипт PHP для подключения к базе данных MySQL, созданной нами на шаге 1. Этот скрипт подготовит три образца продуктов и вставит их в таблицу products.

      Для создания кода PHP откройте новый файл в текстовом редакторе:

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

      Введите в файл следующую информацию и замените PASSWORD паролем пользователя test_user, созданным на шаге 1:

      /var/www/html/config.php

      <?php
      
      define('DB_NAME', 'test_company');
      define('DB_USER', 'test_user');
      define('DB_PASSWORD', 'PASSWORD');
      define('DB_HOST', 'localhost');
      
      $pdo = new PDO("mysql:host=" . DB_HOST . "; dbname=" . DB_NAME, DB_USER, DB_PASSWORD);
      $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
      $pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
      
      

      Сохраните и закройте файл.

      В этом файле мы использовали четыре константы PHP для подключения к базе данных MySQL, созданной на шаге 1:

      • DB_NAME : эта константа хранит название базы данных test_company.

      • DB_USER : эта переменная хранит имя пользователя test_user.

      • DB_PASSWORD : эта константа хранит ПАРОЛЬ MySQL для учетной записи test_user.

      • DB_HOST: сервер, где располагается база данных. В данном случае мы используем сервер localhost.

      Следующая строка в вашем файле инициирует объект данных PHP (PDO) и выполняет подключение к базе данных MySQL:

      ...
      $pdo = new PDO("mysql:host=" . DB_HOST . "; dbname=" . DB_NAME, DB_USER, DB_PASSWORD);
      ...
      

      Ближе к концу файла мы зададим пару атрибутов PDO:

      • ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION: этот атрибут предписывает PDO выдать исключение, которое можно зарегистрировать для целей отладки.
      • ATTR_EMULATE_PREPARES, false: эта опция повышает безопасности, предписывая СУБД MySQL выполнять подготовку вместо PDO.

      Мы добавим файл /var/www/html/config.php в два скрипта PHP для вставки и получения записей, которые мы сейчас создадим.

      Вначале создайте скрипт PHP /var/www/html/insert_products.php для вставки записей в таблицу products:

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

      Затем добавьте следующую информацию в файл /var/www/html/insert_products.php:

      /var/www/html/insert_products.php

      <?php
      
      require_once 'config.php';
      
      $products = [];
      
      $products[] = [
                    'product_name' => 'VIRTUAL SERVERS',
                    'price' => 5,
                    'product_image' => file_get_contents("https://i.imgur.com/VEIKbp0.png")
                    ];
      
      $products[] = [
                    'product_name' => 'MANAGED KUBERNETES',
                    'price' => 30,
                    'product_image' => file_get_contents("https://i.imgur.com/cCc9Gw9.png")
                    ];
      
      $products[] = [
                    'product_name' => 'MySQL DATABASES',
                    'price' => 15,
                    'product_image' => file_get_contents("https://i.imgur.com/UYcHkKD.png" )
                    ];
      
      $sql = "INSERT INTO products(product_name, price, product_image) VALUES (:product_name, :price, :product_image)";
      
      foreach ($products as $product) {
          $stmt = $pdo->prepare($sql);
          $stmt->execute($product);
      }
      
      echo "Records inserted successfully";
      

      Сохраните и закройте файл.

      Вы добавили файл config.php в верхней части файла. Это первый файл, который вы создали для определения переменных базы данных и подключения к базе данных. Также этот файл инициирует объект PDO и сохраняет его в переменной $pdo.

      Далее вы создали массив данных о продуктах, которые нужно вставить в базу данных. Помимо значений product_name и price, подготовленных в виде текстовых и числовых значений соответственно, данный скрипт использует встроенную функцию PHP file_get_contents для чтения изображений из внешнего источника и передачи их в виде строк в столбец product_image.

      Затем вы подготовили выражение SQL и использовали выражение PHP foreach{...} для вставки каждого продукта в базу данных.

      Для выполнения файла /var/www/html/insert_products.php запустите его в окне браузера, используя следующий URL. Замените your-server-IP публичным IP-адресом вашего сервера:

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

      После выполнения файла вы получите в браузере сообщение, подтверждающее успешную вставку записей в базу данных.

      Сообщение об успешной вставке записей в базу данных

      Вы успешно вставили три записи с изображениями продуктов в таблицу products. На следующем шаге мы создадим скрипт PHP для извлечения этих записей и их вывода в браузере.

      Шаг 3 — Отображение информации о продуктах из базы данных MySQL

      Мы разместили в базе данных информацию о продуктах и их ихображения. Теперь мы создадим еще один скрипт PHP, который будет запрашивать и выводить информацию о продуктах в таблице HTML в браузере.

      Для создания файла введите следующее:

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

      Затем введите в файл следующую информацию:

      /var/www/html/display_products.php

      <html>
        <title>Using BLOB and MySQL</title>
        <body>
      
        <?php
      
        require_once 'config.php';
      
        $sql = "SELECT * FROM products";
        $stmt = $pdo->prepare($sql);
        $stmt->execute();
        ?>
      
        <table border="1" align = 'center'> <caption>Products Database</caption>
          <tr>
            <th>Product Id</th>
            <th>Product Name</th>
            <th>Price</th>
            <th>Product Image</th>
          </tr>
      
        <?php
        while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
            echo '<tr>';
            echo '<td>' . $row['product_id'] . '</td>';
            echo '<td>' . $row['product_name'] . '</td>';
            echo '<td>' . $row['price'] . '</td>';
            echo '<td>' .
            '<img src = "data:image/png;base64,' . base64_encode($row['product_image']) . '" width = "50px" height = "50px"/>'
            . '</td>';
            echo '</tr>';
        }
        ?>
      
        </table>
        </body>
      </html>
      

      Сохраните изменения в файле и закройте его.

      Здесь мы опять использовали файл config.php для подключения к базе данных. Затем мы подготовили и выполнили команду SQL, используя PDO для извлечения всех элементов из таблицы products с помощью команды SELECT * FROM products.

      Затем мы создали таблицу HTML и заполнили ее данными о продуктах, используя выражение PHP while() {...}. Строка $row = $stmt->fetch(PDO::FETCH_ASSOC) отправляет запрос в базу данных и сохраняет результат в переменной $row как многомерный массив, который затем отображается как столбец таблицы HTML с использованием синтаксиса $row['column_name'].

      Изображения из столбца product_image заключены в теги <img src = "">. Мы использовали атрибуты width и height для уменьшения ширины и высоты изображений, чтобы они поместились в столбце таблицы HTML.

      Чтобы конвертировать данные, хранящиеся в объекте типа BLOB, обратно в изображения, мы использовали встроенную функцию PHP base64_encode и следующий синтаксис схемы URI данных:

      data:media_type;base64, base_64_encoded_data
      

      В данном случае image/png — это значение параметра media_type (тип файла), а закодированная строка Base64 из столбца product_image — это данные base_64_encoded_data.

      Выполните в браузере файл display_products.php, введя следующий адрес:

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

      Запустив в браузере файл display_products.php, вы увидите таблицу HTML со списком продуктов и связанных с ними изображений.

      Список продуктов из базы данных MySQL

      Это подтверждает, что скрипт PHP для извлечения изображений из базы данных MySQL работает ожидаемым образом.

      Заключение

      В этом обучающем модуле мы использовали тип данных MySQL BLOB для хранения и вывода изображений в коде PHP в Ubuntu 18.04. Мы увидели основные преимущества хранения изображений в базе данных по сравнению с их хранением в файловой системе. В число этих преимуществ входят портативность, безопасность и удобство резервного копирования. Эта технология будет вам полезна, если вы создаете приложение, для которого требуется хранить информацию и изображения вместе, например, студенческий портал или базу данных сотрудников.

      Дополнительную информацию о поддерживаемых типах данных в MySQL можно найти в руководстве по типам данных MySQL. Если вас интересуют дополнительные материалы по MySQL и PHP, пройдите следующие обучающие модули:



      Source link

      Управление отсортированными наборами данных в Redis


      Введение

      Redis — хранилище ключей в памяти с открытым исходным кодом. В Redis отсортированные наборы данных — это тип данных, аналогичный наборам данных в том, что оба типа являются неповторяющимися группами строк. Разница в том, что каждый участник отсортированного набора связан с баллами, что позволяет им быть отсортироваными от наименьшего количества баллов к наибольшему. Как и в случае наборами данных, каждый участник отсортированного набора должен быть уникальным, хотя несколько участников могут иметь один и тот же балл.

      В этом обучающем руководстве вы узнаете, как создавать отсортированные наборы данных, получать и удалять их участников, а также создавать новые отсортированные наборы из существующих.

      Использование этого руководства

      Это руководство написано в виде шпаргалки с использованием отдельных примеров. Рекомендуем переходить сразу к любому разделу, относящемуся к вашей актуальной задаче.

      Команды, указанные в этом руководстве, были протестированы на сервере Ubuntu 18.04 с версией Redis 4.0.9. Для настройки аналогичной среды вы можете воспользоваться шагом 1 нашего руководства Установка и обеспечение безопасности Redis в Ubuntu 18.04. Мы продемонстрируем, как эти команды ведут себя, выполнив их с помощью redis-cli — интерфейса командной строки Redis. Обратите внимание, что если вы используете другой интерфейс Redis, например Redli, конкретный вывод некоторых команд может отличаться.

      Также вы можете предоставить управляемый экземпляр базы данных Redis для тестирования этих команд, но при этом необходимо отметить, что в зависимости от уровня контроля, который используется вашим поставщиком базы данных, некоторые команды этого обучающего руководства могут не работать, как описано. Для предоставления управляемой базы данных DigitalOcean следуйте указаниям нашей документации по управляемым базам данных. Затем вы должны либо установить Redli, либо настроить туннель TLS в целях подключения к управляемой базе данных через TLS.

      Создание отсортированных наборов данных и добавление участников

      Для создания отсортированного набора используйте команду zadd. zadd принимает в качестве аргументов имя ключа, который будет хранить отсортированный набор, за которым следует балл участника, которого вы добавляете, и значение самого участника. Следующая команда создаст ключ отсортированного набора под названием faveGuitarists с одним участником, Joe Pass, который имеет балл 1:

      • zadd faveGuitarists 1 "Joe Pass"

      zadd вернет целое число, указывающее, сколько участников было добавлено в отсортированный набор, если он был успешно создан.

      Output

      (integer) 1

      Вы можете добавить несколько участников в отсортированный набор с помощью zadd. Обратите внимание, что их баллы не должны быть последовательными — могут быть пробелы между баллами, и несколько участников, находящихся в одном и том же отсортированном наборе, могут иметь один и тот же балл:

      • zadd faveGuitarists 4 "Stephen Malkmus" 2 "Rosetta Tharpe" 3 "Bola Sete" 3 "Doug Martsch" 8 "Elizabeth Cotten" 12 "Nancy Wilson" 4 "Memphis Minnie" 12 "Michael Houser"

      Output

      (integer) 8

      zadd может принимать следующие опции, которые вы должны ввести после имени ключа и перед баллом первого участника:

      • NX или XX: эти опции имеют противоположные действия, поэтому вы можете включать только одну из них в любой операции zadd:
        • NX: указывает zadd не обновлять существующих участников. С этой опцией zadd будет добавлять только новые элементы.
        • XX: указывает zadd обновлять только существующие элементы. С этой опцией zadd никогда не будет добавлять новых участников.
      • CH. Как правило, zadd возвращает только количество новых элементов, добавленных в отсортированный набор. Но если эта опция включена, zadd будет возвращать количество измененных элементов. Сюда входят новые добавленные участники и участники, баллы которых были изменены.
      • INCR: заставляет команду увеличить значение балла участника. Если участник еще не существует, команда добавит его в отсортированный набор с увеличением в качестве его балла, как если бы его первоначальный балл был равен 0. Если INCR включен, zadd будет возвращать новый балл участника, если операция успешна. Обратите внимание, что вы можете включать только одну пару «балл/участник» в момент использования этой опции.

      Вместо передачи опции INCR в zadd вы можете использовать команду zincrby, которая ведет себя точно так же. Вместо того чтобы присваивать участнику отсортированного набора значение, указанное значением балла как zadd, она увеличивает балл этого участника на это значение. Например, следующая команда увеличивает балл участника Stephen Malkmus, который был первоначально равен 4 и увеличился на 5 до 9.

      • zincrby faveGuitarists 5 "Stephen Malkmus"

      Output

      "9"

      Как и в случае с опцией INCR команды zadd, если указанный участник не существует, то zincrby создаст его со значением увеличения в качестве его балла.

      Получение участников из отсортированных наборов

      Наиболее основополагающий способ получения участников, удерживаемых в отсортированном наборе — использовать команду zrange. Эта команда принимает в качестве аргументов имя ключа, участников которого вы хотите получить, и ряд участников, находящихся в нем. Диапазон ряда определяется двумя числами, представляющими нулевые индексы — это означает, что 0 представляет первого участника отсортированного набора (или участника с наименьшим баллом), 1 представляет следующего и т. д.

      Следующий пример вернет первые четыре участника из отсортированного набора faveGuitarists, созданного в предыдущем разделе:

      • zrange faveGuitarists 0 3

      Output

      1) "Joe Pass" 2) "Rosetta Tharpe" 3) "Bola Sete" 4) "Doug Martsch"

      Обратите внимание, что если отсортированный набор, который вы передаете в zrange​​​, имеет два или несколько элементов, которые имеют один и тот же балл, он будет обрабатывать эти элементы в лексикографическом или в алфавитном порядке.

      Индексы start и stop могут также быть отрицательными числами, где -1 представляет последнего участника, -2 представляет предпоследнего участника и т. д.:

      • zrange faveGuitarists -5 -2

      Output

      1) "Memphis Minnie" 2) "Elizabeth Cotten" 3) "Stephen Malkmus" 4) "Michael Houser"

      zrange может принимать аргумент WITHSCORES, который, при его включении, будет также возвращать баллы участников:

      • zrange faveGuitarists 5 6 WITHSCORES

      Output

      1) "Elizabeth Cotten" 2) "8" 3) "Stephen Malkmus" 4) "9"

      zrange может возвращать только ряд участников в восходящей числовой последовательности. Чтобы отменить это и вернуть диапазон в нисходящей последовательности, необходимо использовать команду zrevrange. Эту команду можно представить как временно обращающую порядок данного отсортированного набора перед возвратом участников, находящихся в указанном диапазоне. Таким образом, с zrevrange 0 будет представлять последнего участника, содержащегося в ключе, 1 будет представлять предпоследнего и т. д.:

      • zrevrange faveGuitarists 0 5

      Output

      1) "Nancy Wilson" 2) "Michael Houser" 3) "Stephen Malkmus" 4) "Elizabeth Cotten" 5) "Memphis Minnie" 6) "Doug Martsch"

      zrevrange может также принимать опцию WITHSCORES.

      Вы можете возвращать ряд участников на основании их баллов с помощью команды zrangebyscore. В следующем примере команда будет возвращать любого участника, удерживаемого в ключе faveGuitarists с баллом 2, 3 или 4:

      • zrangebyscore faveGuitarists 2 4

      Output

      1) "Rosetta Tharpe" 2) "Bola Sete" 3) "Doug Martsch" 4) "Memphis Minnie"

      В данном примере диапазон инклюзивный, т. е. он будет возвращать участников с баллами 2 или 4. Можете исключить любой конец диапазона, поставив перед ним открывающую скобку (​​​(​​​). Следующий пример будет возвращать каждого участника с баллом выше или равным 2, но ниже 4:

      • zrangebyscore faveGuitarists 2 (4

      Output

      1) "Rosetta Tharpe" 2) "Bola Sete" 3) "Doug Martsch"

      Как и в случае с zrange, zrangebyscore может принимать аргумент WITHSCORES. Он также принимает опцию LIMIT, которую вы можете использовать для получения только выбранных элементов из вывода zrangebyscore. Эта опция принимает offset, который является первым участником в диапазоне, который будет возвращать команда, и count, который определяет, сколько участников команда будет возвращать в общей сложности. Например, следующая команда будет рассматривать первые шесть участников отсортированного набора faveGuitarists, но будет возвращать только три участника из него, начиная со второго участника в диапазоне, представленного 1:

      • zrangebyscore faveGuitarists 0 5 LIMIT 1 3

      Output

      1) "Rosetta Tharpe" 2) "Bola Sete" 3) "Doug Martsch"

      Команда zrevrangebyscore возвращает обращенный ряд участников на основе их баллов. Следующая команда возвращает каждого участника набора с балом между 10 и 6:

      • zrevrangebyscore faveGuitarists 10 6

      Output

      1) "Stephen Malkmus" 2) "Elizabeth Cotten"

      Как и в случае с zrangebyscore, zrevrangebyscore может принимать обе опции WITHSCORES и LIMIT. Также вы можете исключать любой конец диапазона, ставя перед ним открытую скобку.

      Возможно, будут случаи, когда у всех участников отсортированного набора будет один и тот же балл. В таком случае вы можете при помощи redis возвратить ряд элементов, отсортированных лексикографически или в алфавитном порядке, с помощью команды zrangebylex. Чтобы попробовать эту команду, можно запустить следующую команду zadd для создания отсортированного набора, где каждый участник имеет один и тот же балл:

      • zadd SomervilleSquares 0 Davis 0 Inman 0 Union 0 porter 0 magoun 0 ball 0 assembly

      Перед zrangebylex должно идти имя ключа, интервал запуска и интервал остановки. Интервалы запуска и остановки должны начинаться с открытой скобки (() или открытой квадратной скобки ([) — например, следующим образом:

      • zrangebylex SomervilleSquares [a [z

      Output

      1) "assembly" 2) "ball" 3) "magoun" 4) "porter"

      Обратите внимание, что этот пример возвращает только четыре из восьми участников в наборе, даже если команда запросила диапазон от a до z. Это вызвано тем, что значения Redis чувствительны к регистру, поэтому участники, начинающиеся с заглавной буквы, были исключены из ее вывода. Для их возврата вы можете запустить следующее:

      • zrangebylex SomervilleSquares [A [z

      Output

      1) "Davis" 2) "Inman" 3) "Union" 4) "assembly" 5) "ball" 6) "magoun" 7) "porter"

      zrangebylex также принимает специальные символы -, т. е. минус бесконечность, и +, т. е. плюс бесконечность. Таким образом, следующий синтаксис команды будет также возвращать каждого участника отсортированного набора:

      • zrangebylex SomervilleSquares - +

      Обратите внимание, что zrangebylex не может возвращать участников отсортированных наборов в обратном лексикографическом (восходящем алфавитном) порядке. Для этого нужно использовать zrevrangebylex:

      • zrevrangebylex SomervilleSquares + -

      Output

      1) "porter" 2) "magoun" 3) "ball" 4) "assembly" 5) "Union" 6) "Inman" 7) "Davis"

      Поскольку она предназначена для использования с отсортированными наборами данных, где каждый участник имеет один и тот же балл, zrangebylex не принимает опцию WITHSCORES. Однако она принимает опцию LIMIT.

      Получение информации по отсортированным наборам

      Для определения того, сколько участников находится в заданном отсортированном наборе (т. е. для определения его кардинальности), нужно использовать команду zcard. Следующий пример показывает, сколько участников хранится в ключе faveGuitarists из первого раздела этого руководства:

      Output

      (integer) 9

      zcount может указать, сколько элементов хранится в определенном отсортированном наборе, который находится в диапазоне баллов. Первое число после ключа — начало диапазона, второе — конец диапазона:

      • zcount faveGuitarists 3 8

      Output

      (integer) 4

      zscore выводит балл указанного участника отсортированного набора:

      • zscore faveGuitarists "Bola Sete"

      Output

      "3"

      Если либо указанный участник, либо ключ не существует, zscore будет возвращать (nil).

      zrank аналогичен zscore, но вместо того чтобы возвращать балл данного участника, он возвращает его ранг. В Redis ранг — нулевой индекс участников отсортированного набора в порядке их баллов. Например, Joe Pass имеет балл 1, но, поскольку это самый низкий балл любого участника в ключе, он имеет ранг 0:

      • zrank faveGuitarists "Joe Pass"

      Output

      (integer) 0

      Есть другая команда Redis под названием zrevrank, выполняющая ту же функцию, что и zrank, но вместо этого обращающая ранги участников в наборе. В следующем примере Joe Pass имеет самый низкий балл и, соответственно, самый высокий обращенный ранг:

      • zrevrank faveGuitarists "Joe Pass"

      Output

      (integer) 8

      Единственное отношение между баллом участника и его рангом — положение данного балла в сравнении с другими участниками. Если между двумя последовательными участниками существует разрыв баллов, это не будет отражено в их ранге. Обратите внимание, что если два участника имеют одинаковый балл, то тот, который является первым в алфавитном порядке, будет иметь более низкий ранг.

      Как и zscore, zrank и zrevrank будут возвращать (nil) при отсутствии ключа или участника.

      zlexcount может указать, сколько участников хранится в отсортированном наборе между лексикографическим диапазоном. В следующем примере используется отсортированный набор SomervilleSquares из предыдущего раздела:

      • zlexcount SomervilleSquares [M [t

      Output

      (integer) 5

      Эта команда соответствует тому же синтаксису, что и команда zrangebylex, поэтому подробные данные по определению строки см. в предыдущем разделе.

      Удаление участников из отсортированных наборов

      Команда zrem может удалять один или несколько участников из отсортированного набора:

      • zrem faveGuitarists "Doug Martsch" "Bola Sete"

      zrem будет возвращать целое число, указывающее, сколько участников она удалила из отсортированного набора:

      Output

      (integer) 2

      Есть три команды Redis, которые позволяют удалять участников отсортированного набора на основе диапазона. Например, если каждый участник отсортированного набора имеет одинаковый балл, вы можете удалять участников на основании лексикографического диапазона с помощью zremrangebylex. Эта команда использует тот же синтаксис, что и zrangebylex. Следующий пример удаляет каждого участника, который начинается с заглавной буквы, из ключа SomervilleSquares, созданного в предыдущем разделе:

      • zremrangebylex SomervilleSquares [A [Z

      zremrangebylex выведет целое число, указывающее, сколько участников было удалено:

      Output

      (integer) 3

      Вы можете также удалять участников на основе диапазона баллов с помощью команды zremrangebyscore, которая использует тот же синтаксис, что и команда zrangebyscore. В следующем примере будет удален каждый участник, находящийся в faveGuitarists, с баллом 4, 5 или 6:

      • zremrangebyscore faveGuitarists 4 6

      Output

      (integer) 1

      Вы можете удалять участников из набора на основе диапазона рангов с помощью команды zremrangebyrank, которая использует тот же синтаксис, что и zrangebyrank. Следующая команда удаляет три участника отсортированного набора с самыми низкими рангами, которые определяются диапазоном нулевых индексов:

      • zremrangebyrank faveGuitarists 0 2

      Output

      (integer) 3

      Обратите внимание, что числа, передаваемые в remrangebyrank, могут также быть отрицательными, при этом -1 представляет самый высокий ранг, -2 следующий самый высокий и т. д.

      Создание новых отсортированных наборов из существующих

      Redis содержит две команды, которые позволяют сопоставлять участников нескольких отсортированных наборов и создавать новые на основе этих сопоставлений: zinterstore и zunionstore. Для экспериментирования с этими командами нужно запустить следующие команды zadd для создания некоторых отсортированных наборов в качестве примеров.

      • zadd NewKids 1 "Jonathan" 2 "Jordan" 3 "Joey" 4 "Donnie" 5 "Danny"
      • zadd Nsync 1 "Justin" 2 "Chris" 3 "Joey" 4 "Lance" 5 "JC"

      zinterstore находит участников, которые были представлены в двух или нескольких отсортированных наборах — т. е. данные пересекались — и создает новый отсортированный набор, содержащий только этих участников. Эта команда должна содержать по порядку имя ключа назначения, где будут храниться пересекающиеся участники в качестве отсортированного набора, количество ключей, передаваемых в zinterstore, и имена ключей, которые вы хотите проанализировать:

      • zinterstore BoyBands 2 NewKids Nsync

      zinterstore будет возвращать целое число, показывающее количество элементов, сохраненных в конечном отсортированном наборе. Поскольку NewKids и Nsync имеют только одного общего участника — Joey, команда будет возвращать 1:

      Output

      (integer) 1

      Учтите, что если конечный ключ уже существует, то zinterstore перезапишет его содержимое.

      zunionstore создаст новый отсортированный набор, содержащий каждого участника ключей, переданных в него. Эта команда использует тот же синтаксис, что и zinterstore, и требует имя конечного ключа, количество ключей, передаваемых в команду, и имена ключей:

      • zunionstore SuperGroup 2 NewKids Nsync

      Как и zinterstore, zunionstore будет возвращать целое число, показывающее количество элементов, указанных в конечном ключе. Хотя оба исходных отсортированных набора содержали пять участников, поскольку отсортированные наборы не могут содержать повторяющихся участников, а каждый ключ содержит одного участника под названием Joey, итоговое целое число будет равняться 9:

      Output

      (integer) 9

      Как и zinterstore, zunionstore перезаписывает содержимое конечного ключа, если он уже существует.

      Чтобы предоставить вам возможность лучше контролировать баллы участников при создании новых отсортированных наборов при помощи zinterstore и zunionstore, обе эти команды принимают опции WEIGHTS и AGGREGATE.

      После опции WEIGHTS идет одно число для каждого отсортированного набора, включенного в команду, взвешивающего или перемножающего баллы каждого участника. Первое число после опции WEIGHTS взвешивает баллы первого ключа, переданного команде; второе число взвешивает второй ключ и т. д.

      В качестве следующего примера создается новый отсортированный набор, содержащий пересекающиеся ключи из отсортированных наборов NewKids и Nsync. Он взвешивает баллы в ключе NewKids с коэффициентом 3 и взвешивает баллы в ключе Nsync с коэффициентом 7:

      • zinterstore BoyBandsWeighted 2 NewKids Nsync WEIGHTS 3 7

      Если опция WEIGHTS не включена, взвешивание производится по умолчанию с коэффициентом 1 — как для zinterstore, так и для zunionstore.

      AGGREGATE принимает три подопции. Первая из них, SUM, осуществляет поведение zinterstore и zunionstore по умолчанию, добавляя баллы одинаковых участников в комбинированные наборы.

      Если запускаете операцию zinterstore или zunionstore на двух отсортированных наборах, имеющих одного общего участника, но при этом этот участник имеет разные баллы для каждого набора, то можете заставить операцию назначать более низкий из двух баллов в новом наборе при помощи подопции MIN.

      • zinterstore BoyBandsWeightedMin 2 NewKids Nsync WEIGHTS 3 7 AGGREGATE MIN

      Поскольку два отсортированных набора имеют только одного совпадающего участника с одинаковым баллом (3), эта команда создаст новый набор с участником, равным более низкому значению их двух взвешенных баллов:

      • zscore BoyBandsWeightedMin "Joey"

      Output

      "9"

      Аналогично AGGREGATE может заставить zinterstore или zunionstore назначать более высокий из двух баллов с опцией MAX:

      • zinterstore BoyBandsWeightedMax 2 NewKids Nsync WEIGHTS 3 7 AGGREGATE MAX

      Эта команда создает новый набор с одним участником Joey, который имеет более высокий показатель взвешенного балла из двух:

      • zscore BoyBandsWeightedMax "Joey"

      Output

      "21"

      Возможно, будет полезно рассматривать WEIGHTS как способ временного манипулирования баллами участников перед анализом. Также полезно рассматривать опцию AGGREGATE как способ решать, как контролировать баллы участников перед тем, как добавлять их к новым наборам.

      Заключение

      В этом руководстве приводится информация о ряде команд, используемых для создания и управления отсортированными наборами данных в Redis. Если есть другие связанные команды, аргументы или процедуры, которые вы хотели бы видеть в этом руководстве, просьба обращаться с запросами или предложениями в комментариях ниже.

      Дополнительную информацию о командах Redis можно найти в нашей серии обучающих руководств Управление базой данных Redis.



      Source link

      Отображение данных с помощью DigitalOcean API в Django


      Автор выбрал фонд FreeBSD Foundation для получения пожертвования в рамках программы Write for DOnations.

      Введение

      По мере роста спроса на развитие full-stack разработки появляются структуры веб-приложений, делающие разработку менее обременительной и более эффективной. Django является одной из таких структур. Django используется на крупных сайтах, в том числе Mozilla, Pinterest и Instagram. В отличие от нейтральной микроинфраструктуры Flask, пакет Django PyPI содержит все, что требуется для разработки полного цикла, и не требует настраивать для разработки базу данных или панель управления.

      Django часто используется для вывода информации с API (например, посты Instagram или репозитории GitHub) на ваших сайтах и в веб-приложениях. Хотя это можно сделать и с помощью других структур веб-приложений, политика Django «батарейки в комплекте» означает, что для достижения того же результата потребуется меньше работы и меньше пакетов.

      В этом обучающем модуле мы создадим проект Django, который будет отображать информацию дроплетов вашей учетной записи DigitalOcean с помощью API DigitalOcean v2. В частности, мы создадим сайт, который будет отображать таблицу дроплетов с указанием каждого IP-адреса, идентификатора, региона хостинга и ресурса. Для стилизации страницы на вашем сайте будет использоваться BulmaCSS, чтобы вы могли сосредоточиться на разработке и получить красивый результат.

      После прохождения этого обучающего модуля у вас будет проект Django, который сможет создать веб-страницу следующего вида:

      Шаблон с таблицей данных дроплетов

      Предварительные требования

      Для прохождения этого обучающего руководства вам потребуется следующее:

      • Учетная запись DigitalOcean с не менее чем одним дроплетом и персональным токеном доступа. Обязательно запишите токен в безопасном месте, он потребуется позднее в этом обучающем модуле.
      • Умение делать запросы в API. Подробный обучающий модуль по работе с API можно найти в документе Использование веб-API для Python3.
      • Локальная виртуальная среда для Python для поддержания зависимостей. В этом обучающем модуле мы будем использовать имя do_django_api для нашего каталога проекта и env для нашей виртуальной среды.
      • Знакомство с логикой шаблонов Django для отображения страниц с помощью данных API.
      • Знакомство с логикой представления данных Django для обработки данных, полученных в API, и их передачи в шаблон для отображения.

      Шаг 1 — Создание базового проекта Django

      Установите Django из виртуальной среды env:

      Теперь вы можете запустить проект Django и выполнить некоторые первоначальные команды по настройке.

      Используйте django-admin startproject <name>​​​​​ для создания подкаталога в папке проекта с именем вашего проекта Django, затем переключитесь на этот каталог.

      • django-admin startproject do_django_project
      • cd do_django_project

      После создания подкаталога вы найдете в нем файл manage.py, который обычно используется для взаимодействия с Django и работы вашего проекта. Используйте migrate для обновления базы данных по разработке Django:

      • python3 manage.py migrate

      Вы увидите результат, который будет выглядеть следующим образом, по мере обновления базы данных:

      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

      Далее воспользуйтесь командой runserver для запуска проекта, чтобы протестировать его:

      • python3 manage.py runserver

      Когда запустится сервер, результат будет выглядеть следующим образом:

      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.

      Теперь у нас есть базовый проект Django и работающий сервер разработки. Чтобы просмотреть работающий сервер разработки, откройте в браузере адрес 127.0.0.1:8000. В результате откроется стартовая страница Django:

      Типовая стартовая страница Django

      Далее вы создадите приложение Django и настроите ваш проект для представления в этом приложении, чтобы увидеть нечто более интересное, чем страницу по умолчанию.

      Шаг 2 — Создание базового приложения Django

      На этом шаге вы создадите скелет приложения, который будет хранить ваши результаты дроплета. Вы вернетесь к этому приложению позже, когда настроите вызов API, чтобы наполнить его данными.

      Убедитесь, что находитесь в каталоге do_django_project, и создайте приложение Django с помощью следующей команды:

      • python3 manage.py startapp display_droplets

      Теперь вам нужно добавить новое приложение в INSTALLED_APPS в файле settings.py, чтобы Django распознавал его. settings.py — файл конфигурации Django, расположенный в другом подкаталоге проекта Django; у него такое же имя, как у папки проекта (do_django_project). Django создал для вас обе папки. Перейдите в каталог do_django_project​​​:

      Отредактируйте файл settings.py в редакторе на ваш выбор:

      Добавьте ваше новое приложение в раздел INSTALLED_APPS файла:

      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',
      ]
      

      Сохраните и закройте файл после завершения.

      Функция просмотра GetDroplets

      Далее вы создадите функцию GetDroplets в файле views.py приложения display_droplets​​​2​​​. Эта функция отобразит шаблон, который вы будете использовать для показа данных дроплета как context​​​ из ​​API. context — словарь, используемый для передачи данных из кода Python и отправки их в шаблон HTML для показа на веб-странице.

      Перейдите в каталог display_droplets:

      • cd ..
      • cd display_droplets

      Откройте файл views.py для редактирования:

      Добавьте в файл следующий код:

      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
      

      Сохраните и закройте файл.

      Позже вы заполните эту функцию и создадите файл droplets.html, но сначала давайте настроим файл urls.py для вызова этой функции при посещении корневого каталога сервера разработки (127.0.0.1:8000).

      Перейдите обратно в каталог do_django_project​​:

      • cd ..
      • cd do_django_project

      Откройте файл urls.py​​​​​​ для редактирования:

      Добавьте заявление import для GetDroplets​​, затем добавьте дополнительный путь к urlpatterns, который будет указывать на новое представление.

      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'),
      ]
      

      Если хотите создать собственные настраиваемые пути, первый параметр — URL (например, example.com/**admin**), второй параметр — функция для вызова создания веб-страницы, а третий — только имя пути.

      Сохраните и закройте файл.

      Шаблон дроплетов

      Далее вы будете работать с шаблонами. Шаблоны — файлы HTML, которые Django использует для создания веб-страниц. В этом случае вы будете использовать шаблон для создания страницы HTML, которая отображает данные API.

      Перейдите обратно в каталог display_droplets​​​​​​:

      • cd ..
      • cd display_droplets

      В этом каталоге создайте папку template и перейдите в нее:

      • mkdir templates
      • cd templates

      Создайте файл droplets.html и откройте его для редактирования:

      Во избежание необходимости писать какой-либо CSS для этого проекта, будем использовать Bulma CSS, так как он является бесплатным и компактным CSS-каркасом, позволяющим создавать готовые веб-страницы простым добавлением нескольких атрибутов классов в HTML.

      Теперь создадим шаблон с базовой навигационной панелью. Добавьте в файл droplets.html​​​ следующий код:

      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>
      

      Сохраните и закройте файл.

      Этот код импортирует команду Bulma в стандартный HTML и создает панель nav, показывающую ​​​«Droplets».

      Обновите вкладку браузера, чтобы просмотреть изменения, внесенные в шаблон.

      Шаблон с базовым заголовком

      До сих пор вы не касались ничего, связанного с API; вы создали основу для проекта. Далее вы найдете применение этой странице, создав вызов API и представив данные дроплета.

      Шаг 3 — Создание вызова API

      На этом шаге вы выполните настройку вызова API и отправите данные дроплета как контекст в шаблон для показа в таблице.

      Получение данных дроплета

      Перейдите обратно в каталог display_droplets:

      Установите библиотеку requests, чтобы связываться с API:

      Библиотека requests позволяет коду запрашивать данные в API и добавлять заголовки (дополнительные данные, отправленные вместе с нашим запросом).

      Далее вы создадите файл services.py, в котором будете совершать вызов API. Эта функция будет использовать запросы для связи с https://api.digitalocean.com/v2/droplets и наращивать каждый дроплет в файле JSON, возвращаемом в список.

      Откройте файл services.py​​​​​​​​​​​​ для редактирования:

      Добавьте в файл следующий код:

      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
      

      Внутри функции get_droplets происходит два события: делается запрос и разбираются данные. url содержит URL, запрашивающий данные дроплета из API DigitalOcean. r хранит запрошенные данные.

      requests в этом случае принимает два параметра: url и headers. Если вам нужны данные из другого API, вы можете заменить значение url на соответствующий URL. headers отправляет в DigitalOcean ваш токен доступа, чтобы они знали, что вы можете сделать запрос, а также для какой учетной записи делается запрос.

      droplets содержит информацию из переменной r, но теперь она преобразована из JSON — формата, в котором API направляет информацию — в словарь, который легко использовать в цикле for.

      Следующие три строки создают массив droplet_list[]. После этого цикл for перебирает информацию в дроплетах и добавляет каждый элемент в список. Вся информация, полученная от API и хранимая в дроплетах, находится в документации разработчиков DigitalOcean.

      Примечание. Не забудьте заменить access_token на свой токен доступа. Также не забывайте о безопасности и никогда не публикуйте этот токен онлайн.

      Сохраните и закройте файл.

      Защита вашего токена доступа

      Вы всегда должны скрывать токен доступа, но если кто-то когда-нибудь захочет запустить ваш проект, у вас должен быть простой способ дать им возможность добавлять собственный токен доступа без необходимости редактировать код Python. Для этого подойдет решение DotENV, поскольку переменные хранятся в файле .env, который можно легко отредактировать.

      Перейдите обратно в каталог do_django_project​​:

      Для начала работы с переменными среды установите python-dotenv:

      • pip install python-dotenv

      После установки вам нужно будет настроить Django для обработки переменных среды, чтобы вы могли указывать их в коде. Для этого нужно добавить несколько строк кода в файлы manage.py и wsgi.py.

      Откройте файл manage.py​​ для редактирования:

      Добавьте следующий код:

      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')
      )
      

      Если вы добавляете это в manage.py, это означает, что при подаче команд в Django при разработке он будет обрабатывать переменные среды из вашего файла .env.

      Сохраните и закройте файл.

      Если вам когда-либо потребуется обрабатывать переменные среды в своих производственных проектах, вы можете сделать это из файла wsgi.py. Перейдите в каталог do_django_project​​​​​:

      Откройте файл wsgi.py​​ для редактирования:

      Добавьте следующий код в wsgi.py:

      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()
      

      В этом фрагменте кода есть дополнительный элемент os.path.dirname(), поскольку wsgi.py должен просмотреть два каталога, чтобы найти файл .env. Этот фрагмент — не тот же, что используется для manage.py.

      Сохраните и закройте файл.

      Теперь вы можете использовать переменную среды в файле services.py вместо токена доступа. Перейдите обратно в каталог display_droplets​​​​​​:

      • cd ..
      • cd display_droplets

      Откройте файл services.py​​​​​​​​​​​​ для редактирования:

      Теперь замените свой токен доступа на переменную среды:

      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
      

      Сохраните и закройте файл.

      Следующий шаг — создать файл .env. Перейдите обратно в каталог do_django_project​​:

      Создайте файл .env и откройте его для редактирования:

      В .env добавьте свой токен в качестве переменной DO_ACCESS_TOKEN:

      do_django_api/do_django_project/.env

      DO_ACCESS_TOKEN=access_token
      

      Сохраните и закройте файл.

      Примечание: Добавьте .env в ваш файл .gitignore, чтобы он никогда не включался в ваши операции подтверждения.

      Теперь подключение API настроено и сконфигурировано, и вы также защитили свой токен доступа. Теперь пришло время предоставить пользователю информацию, которую вы нашли.

      Шаг 4 — Обработка данных дроплета в представлениях и шаблонах

      Теперь, когда вы можете делать вызовы API, вам нужно направить данные дроплета в шаблон для рендеринга. Давайте вернемся к заготовке функции GetDroplets, созданной вами ранее в файле views.py. В данной функции вы отправите droplet_list в качестве контекста в шаблон droplets.html.

      Перейдите в каталог display_droplets:

      Откройте файл views.py для редактирования:

      Добавьте следующий код в views.py:

      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
      

      Информация, отправленная в шаблон droplets.html, обрабатывается через словарь context. Поэтому droplets действует как ключ, а массив,возвращаемый от get_droplets(), действует как значение.

      Сохраните и закройте файл.

      Представление данных в шаблоне

      В шаблоне droplets.html вы будете создавать таблицу и заполнять ее с помощью данных дроплета.

      Перейдите в каталог templates​​​:

      Откройте файл droplets.html​​​​​​ для редактирования:

      Добавьте следующий код после элемента nav в droplets.html​​:

      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 %} — цикл итераций через массив дроплетов, полученный из views.py. Каждый дроплет вставляется в строку таблицы. Различные строки {{ droplet.<attribute> }} получают этот атрибут для каждого дроплета в цикле и вставляют его в ячейку таблицы

      Сохраните и закройте файл.

      Обновите браузер и увидите список дроплетов.

      Шаблон с таблицей данных дроплетов

      Теперь вы можете обрабатывать API DigitalOcean внутри ваших проектов Django. Вы взяли данные, извлеченные из API, и вставили их в созданный вами ранее шаблон, чтобы отобразить информацию с обеспечением читаемости и гибкости.

      Заключение

      В этой статье вы создали проект Django, который может отображать информацию дроплета из API DigitalOcean со стилями Bulma CSS. Выполнив этот обучающий модуль, вы научились трем важным навыкам:

      • Как обрабатывать запросы API в Python при помощи запросов и модулей json.
      • Как отображать данные API в проекте Django с использованием логики просмотра и шаблона.
      • Как безопасно обрабатывать ваши токены API при помощи dotenv в Django.

      Теперь, когда вы получили представление об обработке API в Django, вы можете создать собственный проект — либо с использованием другой функции из API DigitalOcean, либо с другим API. Также вы можете ознакомиться с другими обучающими руководствами Django или с аналогичным руководством по микроструктуре веб-приложений React.





      Source link