Django. Работа с Excel.

Основы Python и Django. -> Исключения в Python.

# Ошибки

Ошибки в программе Python возникают при исполнении кода, т. к. процесс компиляции отсутствует.

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

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

Синтаксические ошибки.

Так же известные как ошибки парсинга.

Например такой код вызовет.

while True print 'Hello world'

>>> while True print 'Hello world'
  File "<stdin>", line 1, in ?
    while True print 'Hello world'
                   ^
SyntaxError: invalid syntax

В этом примере мы пропустили знак : Маркер >>> указывает на строку с ошибкой, за которой следует ее номер.

Исключения и их обработка.

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

Например попытаемся поделить два числа, вводимых пользователем с клавиатуры.

x = input('first number: ')
y = input('second number: ')
print('is: %s' % x/y)

>>> TypeError: unsupported operand type(s) for /: 'str' and 'int'

Мы получим исключение несоответствия типов при форматировании строки.

Добавим обработчик исключения.

x = input('first number: ')
y = input('second number: ')
try:
    print('is: %s' % x/y)
except:
    print('Someting went wrong!')

>> Someting went wrong!

Для того, чтобы в случае ошибки вывести причину ее возникновения, нужно ее перехватить.

x = input('first number: ')
y = input('second number: ')
try:
    print('is: %s' % x/y)
except Exception as e:
    print(e)

>>> unsupported operand type(s) for /: 'str' and 'int'

Как определить тип исключения и принять решение, исходя из этого типа?

Каждое исключение имеет тип и мы можем его использовать.

try:
    print 'is: %s' % x/y
except TypeError:
    print 'is: %s' % str(x/y)
except ZeroDivisionError:
    print 'ZeroDivisionError exception!'

TypeError и ZeroDivisionError - это встроенные типы исключений и не требуют их импорта.

Что если нам необходимо что то выполнить независимо от того возникло исключение или нет.

Это может быть полезно для освобождения занятых ресурсов, например базы данных или открытого файла.

Для этого используем finally оператор.

Оператор finally.

Блок, заключенный в эту конструкцию будет выполнен перед тем как покинуть конструкцию try независимо от того было ли исключение или нет.

try:
    print ('is: %s' % x/y)
except TypeError:
    print ('is: %s' % str(x/y))
except ZeroDivisionError:
    print ('ZeroDivisionError exception!')
finally:
    print('Finally block fired!')

>>>
code$ python exeption.py 
first number: 12
second number: 3
unsupported operand type(s) for /: 'str' and 'int'
is: 4
Finally block fired!

Кроме встроенных в python исключений мы можем создавать свои собственные, чтобы иметь возможность их отработать в клиентском коде.

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

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

Это делает оператор rase, который возвращает строку, или строковое представление объекта класса исключения.

В нашем случае это будет выглядить так:

raise AddMoneyError(1000)

Создадим такое исключение.

class AddMoneyError(Exception):
    def __init__(self, value):
        self.value = value
    def __str__(self):
        return repr('User can not add more than %s' % self.value)

Мы создали свой класс исключения и унаследовались от python класса Exception.

Так же определили метод str где вывели описание ошибки используя внутреннюю переменную value для ее форматирования.

class User(object):
    account = 0
    def add(self,amount):
        if amount>1000:
            raise AddMoneyError(1000)
        else:
            self.account = self.account+amount

В клиентском коде попробуем пополнить счет.

user = User()
user.add(10000)
print 'finish operation'

Получаем

raise AddMoneyError(1000)
__main__.AddMoneyError: 'User can not add more than 1000'

Наше исключение сработало и мы можем его обработать.

user = User()
try:
    user.add(10000)
except AddMoneyError as e:
    print e


zdimon@dell:~/www/lyceum/8/code$ python limit_account.py
'User can not add more than 1000'
finish operation
zdimon@dell:~/www/lyceum/8/code$
Основы Python и Django. -> Експорт данных в таблицу Excel.

Создание проекта.

Создание папки проекта.

mkdir exel
cd exel

Виртуальное окружение

установка в систему нужных команд (установщик python pip и virtualenv)

sudo apt-get install python3-pip virtualenv

установка виртуального окружения в проект

virtualenv -p python3 venv
  • создается папка venv где будут requirements-ы, которую обычно игнорят в git.

Активация виртуального окружения

. ./venv/bin/activate

появляется приставка (venv) в начале коммандной строки что значит что окружение активировано и мы можем устанавливать в него необходимы пакеты

Установка Django

pip install django

Создание нового проекта

django-admin startproject prj

Создание приложения

cd djangoprj
./manage.py startapp main

Прописываем название нового приложения в настройках djangoprj/settings.py

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'main'
]

Запуск сервера разработки.

./manage.py runserver 9898

Установка системных библиотек для работы с MySQL.

sudo apt-get install python3-dev libmysqlclient-dev build-essential

Установка клиента MySQL.

pip install mysqlclient

Прописываем коннект к базе в settings.py.

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'OPTIONS': {
            'read_default_file': './prj/my.cnf',
        },
    }
}

Файл prj/my.cnf

[client]
database = locotrade_new
user = root
password = password
default-character-set = utf8

Создаем файл с классами моделей существующей БД.

./manage.py inspectdb > out-models.py

Скопируем из файла out-models.py класс с пользователями в файл main/models.py.

class Users(models.Model):
    email = models.CharField(unique=True, max_length=191)
    password = models.CharField(max_length=191)
    active = models.IntegerField()
    remember_token = models.CharField(max_length=100, blank=True, null=True)
    created_at = models.DateTimeField(blank=True, null=True)
    updated_at = models.DateTimeField(blank=True, null=True)
    deleted_at = models.DateTimeField(blank=True, null=True)
    first_name = models.CharField(max_length=191, blank=True, null=True)
    last_name = models.CharField(max_length=191, blank=True, null=True)
    phone = models.CharField(max_length=191, blank=True, null=True)

    class Meta:
        managed = False
        db_table = 'users'

Создадим новую команду.

cd main
mkdir  management
touch management/__init__.py
mkdir management/command
touch management/command/__init__.py
touch management/command/load_users.py

Файл load_users.py.

from django.core.management.base import BaseCommand, CommandError

class Command(BaseCommand):

    def handle(self, *args, **options):
        print('Load Users')

Запуск команды.

./manage.py load_users

Проходим циклом по таблице с пользователями.

print('Load Users')
for user in Users.objects.all():
    print(user.email)

Установка библиотеки для работы с xls файлами НА ЗАПИСЬ!.

Документация

pip install xlwt

Создание файла exel.

Запись данных в ячейки таблицы

wb = xlwt.Workbook()
ws = wb.add_sheet('A Test Sheet')
ws.write(0, 0, 'Hello world!!!')
ws.write(0, 1, 12345)
wb.save('example.xls')')