Django model підказки

on_delete=models.опція:

CASCADE: When the referenced object is deleted, also delete the objects that have references to it (when you remove a blog post for instance, you might want to delete comments as well). SQL equivalent: CASCADE.
PROTECT: Forbid the deletion of the referenced object. To delete it you will have to delete all objects that reference it manually. SQL equivalent: RESTRICT.
RESTRICT: (introduced in Django 3.1) Similar behavior as PROTECT that matches SQL’s RESTRICT more accurately. (See django documentation example)
SET_NULL: Set the reference to NULL (requires the field to be nullable). For instance, when you delete a User, you might want to keep the comments he posted on blog posts, but say it was posted by an anonymous (or deleted) user. SQL equivalent: SET NULL.
SET_DEFAULT: Set the default value. SQL equivalent: SET DEFAULT.
SET(…): Set a given value. This one is not part of the SQL standard and is entirely handled by Django.
DO_NOTHING: Probably a very bad idea since this would create integrity issues in your database (referencing an object that actually doesn’t exist). SQL equivalent: NO ACTION. (2)

Django database питання

Важливі моменти по роботі з базами данних в ORM Django.

Якщо існує база данних і її треба підключити до проекту.

Треба робити щось схоже на таке:

  1. налаштовати підключення бази данних ( підключення default)
  2. створити модель бази командою python manage.py inspectdb --database=default
  3. скопіювати створену модель до файлу застосунку appname\models.py
  4. база  підключена. Цілком можливо, треба буде десь виправити недоліки, та в цілому- проект готовий  до роботи з базою

Якщо баз данних декілька

налаштування підключення у файлі проекту settings.py

  1. DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.sqlite3',
            'NAME': BASE_DIR / 'db.sqlite3',
    },
        "filmbase": {
            "ENGINE": "mssql",
            "NAME": "SBase",
            "USER": "User",
            "PASSWORD": "********",
            "HOST": "Server",
            "PORT": "1433",
            "OPTIONS": {"driver": "ODBC Driver 17 for SQL Server",
                       },
        },
    }  # показано як підключити БД MSSQL [pip install django mssql-django]
  2. при запитах використовувати конструкцію item.objects.using('filmbase').all()
    або завжди вказувати  item.objects.using('default').all()
  3. якщо необхідно обмежити кількість у 10 результатів можливо використати конструкцію (сортування по id або pk)
    item.objects.all().order_by('-id')[:10:1]

Корисні посилання

Підключитись до MSSQL бази http://www.pymssql.org/pymssql_examples.html http://www.pymssql.org/freetds.html

Django та версії Python

Тут і тут є таблиця сумісності яку про всяк випадок продублюю в себе

django CMSPythonDjango
 3.93.83.73.63.53.43.23.13.02.22.12.01.11
4.0.x×××××
3.9.x×××××
3.8.x××xLTS×××
3.7.x×xxLTSLTS
3.6.x××xxx
3.5.x××xx××××
3.4.5×××xx××××LTS

 

Django versionPython versions
2.23.5, 3.6, 3.7, 3.8 (added in 2.2.8), 3.9 (added in 2.2.17)
3.03.6, 3.7, 3.8, 3.9 (added in 3.0.11)
3.13.6, 3.7, 3.8, 3.9 (added in 3.1.3)
3.23.6, 3.7, 3.8, 3.9, 3.10 (added in 3.2.9)
4.03.8, 3.9, 3.10

Магічні методи (dunder )

Магічні методи це методи, що виконуються без явного виклику(__init__, __add__, __len__, __repr__ та інші). Термін: dunder  = double undescore.

Тут опишу те, що використовую або планую використовувати. Як підказку (така собі cheatsheet)

__init__(self, par1, par2, …. parN): # використовується для створення властивостей класу.

створює властивості об”єкту під час створення. приклад:

new_object = Class(par1, par2, …. parN)

 

Ubuntu – переглянути встановлені застосунки

Зазвичай все просто. Тут декілька простих способів дізнатися що саме встановлено у Вашій Убунті (кожен метод з новой строки):

apt list --installed
dpkg --get-selections | grep -v deinstall
dpkg --get-selections | grep -v deinstall > ~/packages.txt
dpkg -l
aptitude search '~i!~M'
dpkg --get-selections > ~/packages1.txt

Якщо необхідно встановити те саме (що назбирали вище) на інший сервер (або робочу станцію)

cat ~/packages.txt > sudo dpkg –set-selections && sudo apt-get dselect upgrade

або

sudo dpkg –set-selections < ~/packages.txt && sudo apt-get -u dselect-upgrade

або

dpkg --clear-selections
sudo dpkg --set-selections < ~/packages1.txt

info from there

Juniper OS (EX-2300, 4550) команди для cli-режиму

Це мій записник як доналаштувати комутатор. Все так чи інакше. налаштовано, комутатор в продакшені (працює, не можемо вимкнути надовго).

1 та найважливіше- як відкотити невдалий commit або відновити налаштування на той день коли все було добре (коли щось пішло не так а ми не знаємо коли воно таким стало):

# rollback ?
Possible completions:
<[Enter]> Execute this command
0 2021-03-12 14:39:15 EET by admin via cli
1 2021-03-12 10:29:24 EET by admin via cli
2 2021-03-12 10:26:40 EET by admin via cli
3 2021-03-12 10:24:25 EET by admin via cli
4 2021-03-12 10:18:45 EET by admin via cli
5 2021-03-12 10:16:27 EET by admin via cli
6 2021-03-12 10:10:04 EET by admin via cli
7 2021-03-12 10:09:22 EET by admin via cli
8 2021-03-12 10:09:04 EET by admin via cli
9 2021-03-12 10:07:38 EET by admin via cli
10 2021-03-09 11:51:40 EET by admin via cli
11 2021-03-01 14:21:07 EET by admin via cli
12 2020-12-07 14:13:47 EET by admin via cli

нам треба повернутися, наприклад до 2020-12-07 14:13:47 EET
# rollback 12
# commit

і все працює як було на той момент.

команда rollback без аргументів відміняє зміни, які були зроблені в поточній сесії

Django: проект для кіно Частина 1

Виникла ідея переробити застосунок, який допомагає робити кіно. Почав з Telegram-Bot та складність почала зростати і прийняв рішення почати спочатку та врахувати особливості та побажання співробітників, хто був дотичний до проекту.

Отже, які зміни:

  • вся інформація зберігається в базі даних (розробка:sqlite, продакшен:postgreSQL)
  • зробити WEB-інтерфейс (Django)
  • інтеграція/сумісна робота Django та Telegram-Бота

ці зміни спрощують роботу над проектом та дозволяють не закидати в телеграм те, що там складно зробити (ну хоча-б на початку розробки)

route: якщо є два шлюзи

Так склалося, що сервер має два рівнозначні підключення (DHCP with GW на кожному інтерфейсі). Треба один прибрати.

Як воно було

# ip route show
default via 192.18.7.1 dev eno2
default via 10.1.1.1 dev eno1 proto dhcp src 10.1.1.21 metric 100
10.1.1.0/24 dev eno1 proto kernel scope link src 10.1.1.21
10.1.1.1 dev eno1 proto dhcp scope link src 10.1.1.21 metric 100
192.18.7.0/24 dev eno2 proto kernel scope link src 192.18.7.11

Вирішено так:

# ip route del default via 192.18.7.1 dev eno2
# ip route show
default via 10.1.1.1 dev eno1 proto dhcp src 10.1.1.21 metric 100
10.1.1.0/24 dev eno1 proto kernel scope link src 10.1.1.21
10.1.1.1 dev eno1 proto dhcp scope link src 10.1.1.21 metric 100
192.18.7.0/24 dev eno2 proto kernel scope link src 192.18.7.11

відповідно, в крон бо при переключенні чи перезавантаженні – воно буде знову тут

mdadm: Перевірка стану, заміна диску.

Сервер з mdadm Raid6 на Ubuntu 20
диски в масивах треба регулярно перевіряти. Знайшов bash-скрипт і трохи вдосконалив:
#!/bin/bash
for i in {a..q}; do
echo "Disk sd$i" $SN $MD
smartctl -i -A /dev/sd$i |grep -E "^ "5"|^"197"|^"198"|"FAILING_NOW"|"Serial""
done

Несподівано, на одному з дисків

Disk sdq
Device Model: HGST HUH721008ALE604
Serial Number: 1SGUPUEZ
5 Reallocated_Sector_Ct 0x0033 100 100 005 Pre-fail Always - 0
197 Current_Pending_Sector 0x0022 100 100 000 Old_age Always - 2048
198 Offline_Uncorrectable 0x0008 100 100 000 Old_age Offline - 1170

диск розбито так (fdisk -l):

Disk /dev/sdq: 7.28 TiB, 8001563222016 bytes, 15628053168 sectors
Disk model: HGST HUH721008AL
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes
Disklabel type: gpt
Disk identifier: 492E1319-B4D8-4E83-94AB-C9FFD86EDB4B

Device Start End Sectors Size Type
/dev/sdq1 2048 15628053134 15628051087 7.3T Linux filesystem

новий диск розбиваю так само, все по дефолту –  створив партицію на весь диск, вона автоматично активна. Далі робота по заміні диску:

Перед вимкненням серверу – виймаю диск з масиву:

mdadm –manage /dev/md0 –fail /dev/sdq1

mdadm –manage /dev/md0 –remove /dev/sdq1

Після заміни диску – увімкнув сервер і додав до масиву (попередньо впевнився шо масив не в статусі ребілд):

mdadm –manage /dev/md0 –add /dev/sdq1

Перевіряю, що з масивом:

# cat /proc/mdstat
Personalities : [linear] [multipath] [raid0] [raid1] [raid6] [raid5] [raid4] [raid10]
md0 : active raid6 sdq1[16] sdb1[0] sdp1[14] sdo1[13] sdn1[12] sdm1[11] sdl1[10] sdk1[9] sdh1[8] sdj1[7] sdi1[6] sdg1[5] sdf1[4] sde1[3] sdd1[2] sdc1[1]
109394503680 blocks super 1.2 level 6, 512k chunk, algorithm 2 [16/15] [UUUUUUUUUUUUUUU_]
[==>..................] recovery = 10.1% (789455804/7813893120) finish=706.7min speed=165644K/sec
bitmap: 0/59 pages [0KB], 65536KB chunk

unused devices: <none>

Власне – готово.

І тут як буває – не все гаразд, при перезавантаженні не бачить md0 не збирає його автоматично.

Рішення:

fstab – монтую по ID (бо при створенні може створитись не md0 а, наприклад md170)

/dev/disk/by-uuid/74e7a502-f59d-4156-99cb-517e0bbecc70 /var/nc_data ext4 defaults,nofail,discard 0 0

Та за розкладом запускаю щось таке:

#crontab -l
*/15 * * * * /opt/raid-check.sh
# cat /opt/raid-check.sh
#!/bin/bash
file=/dev/md0
if [ ! -e "$file" ]; then
echo "File does not exist"
mdadm --assemble --scan
mount -a
else
echo "File exists"
fi
як правильно виконати задачу не знайшов, бо вирішив так (пропонують додавати в ініт свої скрипти, наприклад, що як на мене – те саме)

Додатково для зацікавлених. Довідкова інформація:

конфіг масиву:

# cat /proc/mdstat
Personalities : [linear] [multipath] [raid0] [raid1] [raid6] [raid5] [raid4] [raid10]
md0 : active raid6 sdc1[0] sdq1[15] sdp1[14] sdo1[13] sdn1[12] sdm1[11] sdl1[10] sdk1[9] sdh1[8] sdj1[7] sdi1[6] sdg1[5] sdf1[4] sde1[3] sdd1[2] sdb1[1]
109394503680 blocks super 1.2 level 6, 512k chunk, algorithm 2 [16/16] [UUUUUUUUUUUUUUUU]
bitmap: 0/59 pages [0KB], 65536KB chunk

unused devices: <none>

# cat /etc/mdadm/mdadm.conf
ARRAY /dev/md/oc-server:0 level=raid6 num-devices=16 metadata=1.2 name=oc-server:0 UUID=909ef785:11edea8c:0d9c5b27:5c3c4df3
devices=/dev/sdb1,/dev/sdc1,/dev/sdd1,/dev/sde1,/dev/sdf1,/dev/sdg1,/dev/sdh1,/dev/sdi1,/dev/sdj1,/dev/sdk1,/dev/sdl1,/dev/sdm1,/dev/sdn1,/dev/sdo1,/dev/sdp1,/dev/sdq1
DEVICE /dev/sdb1 /dev/sdc1 /dev/sdd1 /dev/sde1 /dev/sdf1 /dev/sdg1 /dev/sdh1 /dev/sdi1 /dev/sdj1 /dev/sdk1 /dev/sdl1 /dev/sdm1 /dev/sdn1 /dev/sdo1 /dev/sdp1 /dev/sdq1
CREATE owner=root group=disk mode=0660 auto=yes
ARRAY /dev/md0 UUID=909ef785:11edea8c:0d9c5b27:5c3c4df3

# cat /etc/fstab
# /etc/fstab: static file system information.
# <file system> <mount point> <type> <options> <dump> <pass>
# / was on /dev/sda2 during curtin installation
/dev/disk/by-uuid/67958d42-a663-4c1b-8a9c-f8d2e20b6a03 / ext4 defaults 0 0
# /boot/efi was on /dev/sda1 during curtin installation
/dev/disk/by-uuid/AEE0-4B33 /boot/efi vfat defaults 0 0
/swap.img none swap sw 0 0
/dev/disk/by-uuid/74e7a502-f59d-4156-99cb-517e0bbecc70 /var/nc_data ext4 defaults,nofail,discard 0 0