Index: .idea/sqldialects.xml
===================================================================
--- .idea/sqldialects.xml	(revision 77b2536c76d3a04bc29b398d9805a99f346b55fe)
+++ .idea/sqldialects.xml	(revision d1a8cb0de012b850acb4a2e12229b3ddca3a9a91)
@@ -2,5 +2,8 @@
 <project version="4">
   <component name="SqlDialectMappings">
+    <file url="file://$PROJECT_DIR$/music/triggers/media_type_deletion.sql" dialect="PostgreSQL" />
     <file url="file://$PROJECT_DIR$/music/triggers/normalize_and_validate_customer_email.sql" dialect="PostgreSQL" />
+    <file url="file://$PROJECT_DIR$/music/triggers/prevent_artist_deletion.sql" dialect="PostgreSQL" />
+    <file url="file://$PROJECT_DIR$/music/triggers/prevent_genre_deletion.sql" dialect="PostgreSQL" />
     <file url="file://$PROJECT_DIR$/music/triggers/update_invoice_total_after_delete.sql" dialect="PostgreSQL" />
     <file url="file://$PROJECT_DIR$/music/triggers/update_invoice_total_after_insert.sql" dialect="PostgreSQL" />
Index: music/models.py
===================================================================
--- music/models.py	(revision 77b2536c76d3a04bc29b398d9805a99f346b55fe)
+++ music/models.py	(revision d1a8cb0de012b850acb4a2e12229b3ddca3a9a91)
@@ -163,2 +163,16 @@
     def __str__(self):
         return f"{self.playlist} - {self.track}"
+
+
+class DeletedCustomerLog(models.Model):
+    log_id = models.AutoField(primary_key=True)
+    first_name = models.CharField(max_length=40)
+    last_name = models.CharField(max_length=20)
+    deleted_at = models.DateTimeField()
+
+    class Meta:
+        db_table = 'deleted_customer_log'
+        managed = False
+
+    def __str__(self):
+        return f"{self.first_name} {self.last_name} {self.deleted_at}"
Index: music/triggers/customer_deletion.sql
===================================================================
--- music/triggers/customer_deletion.sql	(revision d1a8cb0de012b850acb4a2e12229b3ddca3a9a91)
+++ music/triggers/customer_deletion.sql	(revision d1a8cb0de012b850acb4a2e12229b3ddca3a9a91)
@@ -0,0 +1,13 @@
+CREATE OR REPLACE FUNCTION customer_deletion()
+RETURNS TRIGGER AS $$
+BEGIN
+    INSERT INTO deleted_customer_log (first_name, last_name, deleted_at)
+    VALUES (OLD.first_name, OLD.last_name, NOW());
+    RETURN OLD;
+END;
+$$ LANGUAGE plpgsql;
+
+CREATE TRIGGER trg_customer_deletion
+AFTER DELETE ON customer
+FOR EACH ROW
+EXECUTE FUNCTION customer_deletion();
Index: music/triggers/media_type_deletion.sql
===================================================================
--- music/triggers/media_type_deletion.sql	(revision d1a8cb0de012b850acb4a2e12229b3ddca3a9a91)
+++ music/triggers/media_type_deletion.sql	(revision d1a8cb0de012b850acb4a2e12229b3ddca3a9a91)
@@ -0,0 +1,20 @@
+CREATE OR REPLACE FUNCTION media_type_deletion()
+RETURNS TRIGGER AS $$
+BEGIN
+    IF OLD.media_type_id = 1 THEN
+        RAISE EXCEPTION 'Cannot delete default media type (MPEG audio file with id = 1).';
+    END IF;
+
+    UPDATE track
+    SET media_type_id = 1
+    WHERE media_type_id = OLD.media_type_id;
+
+    RETURN OLD;
+END;
+$$ LANGUAGE plpgsql;
+
+
+CREATE TRIGGER trg_media_type_deletion
+BEFORE DELETE ON media_type
+FOR EACH ROW
+EXECUTE FUNCTION media_type_deletion();
Index: music/triggers/prevent_artist_deletion.sql
===================================================================
--- music/triggers/prevent_artist_deletion.sql	(revision d1a8cb0de012b850acb4a2e12229b3ddca3a9a91)
+++ music/triggers/prevent_artist_deletion.sql	(revision d1a8cb0de012b850acb4a2e12229b3ddca3a9a91)
@@ -0,0 +1,17 @@
+CREATE OR REPLACE FUNCTION prevent_artist_deletion()
+RETURNS TRIGGER AS $$
+BEGIN
+    IF EXISTS (
+        SELECT 1 FROM album WHERE artist_id = OLD.artist_id
+    ) THEN
+        RAISE EXCEPTION 'Cannot delete artist with albums.';
+    END IF;
+
+    RETURN OLD;
+END;
+$$ LANGUAGE plpgsql;
+
+CREATE TRIGGER trg_prevent_artist_deletion
+BEFORE DELETE ON artist
+FOR EACH ROW
+EXECUTE FUNCTION prevent_artist_deletion();
Index: music/triggers/prevent_genre_deletion.sql
===================================================================
--- music/triggers/prevent_genre_deletion.sql	(revision d1a8cb0de012b850acb4a2e12229b3ddca3a9a91)
+++ music/triggers/prevent_genre_deletion.sql	(revision d1a8cb0de012b850acb4a2e12229b3ddca3a9a91)
@@ -0,0 +1,17 @@
+CREATE OR REPLACE FUNCTION prevent_genre_deletion()
+RETURNS TRIGGER AS $$
+BEGIN
+    IF EXISTS (
+        SELECT 1 FROM track WHERE genre_id = OLD.genre_id
+    ) THEN
+        RAISE EXCEPTION 'Cannot delete genre with a track of it.';
+    END IF;
+
+    RETURN OLD;
+END;
+$$ LANGUAGE plpgsql;
+
+CREATE TRIGGER trg_prevent_genre_deletion
+BEFORE DELETE ON genre
+FOR EACH ROW
+EXECUTE FUNCTION prevent_genre_deletion();
