[gull] [Q] prob. effacement d'object dans django

sneaky56 at gmx.net sneaky56 at gmx.net
Sun Jan 4 19:03:16 CET 2015


salut la foule,

bonne année 2015.
l'introduction étant faite, j'en viens à mon problème (django 1.7 et python3 sous linux, of course). j'ai une classe de modèle (BasicEntry) qui contient deux foreign keys vers la même classe pour les éléments précédent et suivant (liste doublement chaîné). la première entrée est spéciale dans la mesure ou le nom est vide. pour tous les autres, le nom et non nul. mon problème est que lorsque j'essaye d'enlever (removeEntry) l'avant dernière entrée (donc la dernière avec un nom non nul), les deux dernières entrées sont effacées et je ne comprends pas pourquoi.

voici pour les modèles:


class EntryCollection(models.Model):
    name = models.CharField(max_length=10)

    def save(self, *args, **kwargs):
        super(EntryCollection, self).save(*args, **kwargs)
        if BasicEntry.objects.filter(entry_col=self).count() == 0:
            entry = BasicEntry(entry_col=self, next_entry=None, prev_entry=None)
            entry.save()
            entry.next_entry = entry
            entry.prev_entry = entry
            entry.save()


class BasicEntry(models.Model):
    name = models.CharField(max_length=10)
    entry_col = models.ForeignKey(EntryCollection)
    next_entry = models.ForeignKey('BasicEntry', related_name='next', null=True, default=None)
    prev_entry = models.ForeignKey('BasicEntry', related_name='prev', null=True, default=None)

    def addEntry(self, name):
        try_nr = 1
        new_entry = None
        while True:
            try:
                with transaction.atomic():
                    new_entry = BasicEntry(name=name,
                                           entry_col=self.entry_col,
                                           next_entry=self.next_entry,
                                           prev_entry=self)
                    new_entry.save()
                    self.next_entry.prev_entry = new_entry
                    self.next_entry.save()
                    self.next_entry = new_entry
                    if self.prev_entry == self:
                        self.prev_entry = new_entry
                    self.save()
            except IntegrityError as e:
                print('addEntry: try %d' %(try_nr))
                try_nr += 1
                if try_nr >= DB_Transaction_Tries:
                    raise(e)
                time.sleep(DB_Transaction_sleep)
            else:
                break
        return(new_entry)

    def removeEntry(self):
        if self.name == '':
            print('** The "virtual" first track can not be removed!')
            return
        try_nr = 1
        while True:
            try:
                with transaction.atomic():
                    self.prev_entry.next_entry = self.next_entry
                    self.prev_entry.save()
                    self.next_entry.prev_entry = self.prev_entry
                    self.next_entry.save()
                    self.next_entry = None
                    self.prev_entry = None
                    self.save()
                    for entry in BasicEntry.objects.all():
                        print('11** ENTRY = %s' %(entry))
                        #print('11 %s (prev=%s, next=%s)' %(entry.id, entry.prev_entry.id, entry.next_entry.id))
                    print('self prev = %s, self next = %s' %(self.prev_entry, self.next_entry))
                    self.delete()
                    for entry in BasicEntry.objects.all():
                        print('22** ENTRY = %s' %(entry))
                        #print('22 %s (prev=%s, next=%s)' %(entry.id, entry.prev_entry.id, entry.next_entry.id))
            except IntegrityError as e:
                print('removeEntry: try %d' %(try_nr))
                try_nr += 1
                if try_nr >= DB_Transaction_Tries:
                    raise(e)
                time.sleep(DB_Transaction_sleep)
            else:
                break


voici le résultat dans postgres:
django=> select * from entry_test_basicentry order by id;
 id | name  | entry_col_id | next_entry_id | prev_entry_id 
----+-------+--------------+---------------+---------------
 33 |       |           14 |            34 |            35
 34 | test1 |           14 |            35 |            33
 35 | test2 |           14 |            33 |            34
(3 rows)

j'enleve l'id 34:
django=> select * from entry_test_basicentry order by id;
 id | name  | entry_col_id | next_entry_id | prev_entry_id 
----+-------+--------------+---------------+---------------
 33 |       |           14 |            35 |            35
 35 | test2 |           14 |            33 |            33
(2 rows)

j'enleve l'id 35:
django=> select * from entry_test_basicentry order by id;
 id | name | entry_col_id | next_entry_id | prev_entry_id 
----+------+--------------+---------------+---------------
(0 rows)

l'un d'entre vous a-t-il une idée sur le comment du pourquoi? d'autant plus que je m'assure de ne pas avoir de foreign key de l'élément que j'efface vers d'autres entrées.

merci d'avance


tom


More information about the gull mailing list