2009-08-26 8 views
0

J'utilise la classe suivante dans models.py:save() supprime enregistrement existant lors de l'utilisation unique_together dans le modèle Django

class Player(models.Model): 
    id = models.AutoField(primary_key=True) 
    sport = models.CharField(max_length=3, choices=SPORT_CHOICES) 
    yid = models.IntegerField() 
    first = models.CharField(max_length=30) 
    last = models.CharField(max_length=30) 
    team = models.CharField(max_length=3) 
    class Meta: 
     unique_together = (("sport", "yid"),) 

Si le code suivant est exécuté et un joueur avec ce sport/Yid existe déjà dans la base de données, l'enregistrement de ce joueur est supprimé et le nouveau record du joueur est inséré:

for (sport, yid, first, last, team) in NBA_PLAYERS: 
    player = Player(sport=sport, yid=yid, first=first, last=last, team=team) 
    player.save() 

le problème majeur est que l'identifiant autogenerated du nouvel enregistrement est différent de celui id dans l'enregistrement supprimé et d'autres classes qui utilisent Player comme une clé étrangère référencée cet enregistrement avec l'ancien ID.

appels SQL semblent fonctionner correctement:

mysql> insert into swap_player (sport, yid, first, last, team) values ('mlb', 1234, 'Joel', 'Zumaya', 'det'); 
ERROR 1062 (23000): Duplicate entry 'mlb-1234' for key 2 

Voici l'instruction CREATE appel TABLE de Django:

CREATE TABLE `swap_player` (
    `id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY, 
    `sport` varchar(3) NOT NULL, 
    `yid` integer NOT NULL, 
    `first` varchar(30) NOT NULL, 
    `last` varchar(30) NOT NULL, 
    `team` varchar(3) NOT NULL, 
    UNIQUE (`sport`, `yid`) 
) 
; 

L'erreur ne manque que si la fonction de sauvegarde() est lancé par un action sur une page Web (HttpRequest). Si je lance la fonction save() à partir de la ligne de commande python, je reçois l'erreur correcte:

>>> 
>>> p = Player(sport='mlb', yid=1234, first='Joel', last='Zumaya', team='det') 
>>> p.save() 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "/Users/dave/Development/django_trunk/django/db/models/base.py", line 328, in save 
    self.save_base(force_insert=force_insert, force_update=force_update) 
    File "/Users/dave/Development/django_trunk/django/db/models/base.py", line 400, in save_base 
    result = manager._insert(values, return_id=update_pk) 
    File "/Users/dave/Development/django_trunk/django/db/models/manager.py", line 138, in _insert 
    return insert_query(self.model, values, **kwargs) 
    File "/Users/dave/Development/django_trunk/django/db/models/query.py", line 894, in insert_query 
    return query.execute_sql(return_id) 
    File "/Users/dave/Development/django_trunk/django/db/models/sql/subqueries.py", line 309, in execute_sql 
    cursor = super(InsertQuery, self).execute_sql(None) 
    File "/Users/dave/Development/django_trunk/django/db/models/sql/query.py", line 1756, in execute_sql 
    cursor.execute(sql, params) 
    File "/Users/dave/Development/django_trunk/django/db/backends/util.py", line 19, in execute 
    return self.cursor.execute(sql, params) 
    File "/Users/dave/Development/django_trunk/django/db/backends/mysql/base.py", line 83, in execute 
    return self.cursor.execute(query, args) 
    File "build/bdist.macosx-10.5-i386/egg/MySQLdb/cursors.py", line 166, in execute 
    File "build/bdist.macosx-10.5-i386/egg/MySQLdb/connections.py", line 35, in defaulterrorhandler 
_mysql_exceptions.IntegrityError: (1062, "Duplicate entry 'mlb-1234' for key 2") 
>>> connection.queries 
[{'time': '0.000', 'sql': u'INSERT INTO `swap_player` (`sport`, `yid`, `first`, `last`, `team`) VALUES (mlb, 1234, Joel, Zumaya, det)'}] 
>>> 
>>> 

Comment puis-je obtenir la méthode save() à l'erreur si un enregistrement avec le même sport/Yid déjà existe?

Répondre

0

Vous pouvez remplacer la méthode Player: save(). avec quelque chose comme suit. Je ne connais pas les propriétés de unique_together pour savoir si ce que vous vivez indique un bug.

def save(self, *args, **kwargs): 
    try: 
     Player.objects.get(yid = self.yid, sport=self.sport) 
     raise PlayerObjectExists 
    except: 
     return super(Player, self).save(*args, **kwargs) 
+0

Je voudrais savoir que je peux compter sur l'expression unique_together, donc je voudrais éviter d'écraser la méthode save. –

Questions connexes