Revision 26515bc1 snf-cyclades-app/synnefo/db/models.py

b/snf-cyclades-app/synnefo/db/models.py
32 32
from copy import deepcopy
33 33
from django.conf import settings
34 34
from django.db import models
35
from django.db import IntegrityError
36 35

  
37 36
import utils
38 37
from contextlib import contextmanager
......
41 40
from django.conf import settings as snf_settings
42 41
from aes_encrypt import encrypt_db_charfield, decrypt_db_charfield
43 42

  
44
from synnefo.db.managers import ProtectedDeleteManager
45 43
from synnefo.db import pools, fields
46 44

  
47 45
from synnefo.logic.rapi_pool import (get_rapi_client,
......
102 100
                                            null=False)
103 101
    ctotal = models.PositiveIntegerField('Total number of logical processors',
104 102
                                         default=0, null=False)
105
    # Custom object manager to protect from cascade delete
106
    objects = ProtectedDeleteManager()
107 103

  
108 104
    HYPERVISORS = (
109 105
        ("kvm", "Linux KVM hypervisor"),
......
160 156
            self.virtual_machines.filter(deleted=False)\
161 157
                                 .update(backend_hash=self.hash)
162 158

  
163
    def delete(self, *args, **kwargs):
164
        # Integrity Error if non-deleted VMs are associated with Backend
165
        if self.virtual_machines.filter(deleted=False).count():
166
            raise IntegrityError("Non-deleted virtual machines are associated "
167
                                 "with backend: %s" % self)
168
        else:
169
            # ON_DELETE = SET NULL
170
            for vm in self.virtual_machines.all():
171
                vm.backend = None
172
                vm.save()
173
            self.virtual_machines.all().backend = None
174
            # Remove BackendNetworks of this Backend.
175
            # Do not use networks.all().delete(), since delete() method of
176
            # BackendNetwork will not be called!
177
            for net in self.networks.all():
178
                net.delete()
179
            super(Backend, self).delete(*args, **kwargs)
180

  
181 159
    def __init__(self, *args, **kwargs):
182 160
        super(Backend, self).__init__(*args, **kwargs)
183 161
        if not self.pk:
......
320 298
    userid = models.CharField('User ID of the owner', max_length=100,
321 299
                              db_index=True, null=False)
322 300
    backend = models.ForeignKey(Backend, null=True,
323
                                related_name="virtual_machines",)
301
                                related_name="virtual_machines",
302
                                on_delete=models.PROTECT)
324 303
    backend_hash = models.CharField(max_length=128, null=True, editable=False)
325 304
    created = models.DateTimeField(auto_now_add=True)
326 305
    updated = models.DateTimeField(auto_now=True)
......
639 618
    }
640 619

  
641 620
    network = models.ForeignKey(Network, related_name='backend_networks')
642
    backend = models.ForeignKey(Backend, related_name='networks')
621
    backend = models.ForeignKey(Backend, related_name='networks',
622
                                on_delete=models.PROTECT)
643 623
    created = models.DateTimeField(auto_now_add=True)
644 624
    updated = models.DateTimeField(auto_now=True)
645 625
    deleted = models.BooleanField('Deleted', default=False)

Also available in: Unified diff