re-salut,

> 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:
[...]
> 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.

le code est en attachement, car je ne suis pas sur que l'indentation du 
précédent message soit représenté correctement pour tout le monde.


tomas
from django.db import models, IntegrityError, transaction
import time

# Create your models here.

DB_Transaction_Tries = 5
DB_Transaction_Sleep = 0.8      # seconds

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()
                    self.delete()
            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
_______________________________________________
gull mailing list
[email protected]
http://forum.linux-gull.ch/mailman/listinfo/gull

Répondre à