2017-01-20 4 views
2

J'ai un modèle avec les contraintes uniques suivantes:IntegrityError pas élevé sur Aucun

class Record(Model): 
    type = ForeignKey(Type, related_name='records') 
    code = CharField(max_length=32) 
    group = ForeignKey('self', null=True, blank=True, related_name='members') 

    class Meta: 
     unique_together = ('type', 'code', 'group') 

Je veux deux enregistrements être le même s'ils ont tous deux le même type et le code, et les deux ont aucun groupe. Je me attends à une erreur d'intégrité à soulever, mais cela ne se produit pas dans le cas de test suivant:

Record.objects.create(type=type_article_structure, 
         code='shoe', 
         group=None) 
Record.objects.create(type=type_article_structure, 
         code='shoe', 
         group=None) 

La travaille contrainte unique si je remplirai le même groupe pour les deux:

group = Record.objects.create(type=type_article_structure, 
           code='group') 
Record.objects.create(type=type_article_structure, 
         code='shoe', 
         group=group) 
Record.objects.create(type=type_article_structure, 
         code='shoe', 
         group=group) 

Ce résultat dans:

django.db.utils.IntegrityError: UNIQUE constraint failed: md_masterdata_record.type_id, md_masterdata_record.code, md_masterdata_record.group_id 

Comment puis-je m'assurer que j'obtiens la même erreur dans le premier cas?

PS. Mes cas de test utilisent SQLite, mon serveur de production utilise PostgreSQL.

Répondre

4

contrainte ensemble unique est appliqué au niveau de la base de données. De nombreuses bases de données ne se comparent pas null les valeurs les uns des autres et, par conséquent, que les opérations d'insertion d'entrer.

Vous pouvez y remédier en remplaçant la méthode clean dans votre modèle. La méthode clean doit être utilisée pour fournir une validation personnalisée ou pour modifier les valeurs de champs avant l'enregistrement. En outre, notez la méthode is not invoked when you call save save on the object. It should be invoked before calling the.

from django.core.exceptions import ValidationError 
class Record(Model): 
    def clean(self): 
     # check if exists 
     if Record.objects.get(type=self.type, 
          code=self.code, 
          group=self.group): 
       # raise an exception 
       raise ValidationError("Exists") 
+0

Merci pour votre réponse. Malheureusement, je ne comprends pas l'exemple. Ce code ne devrait-il pas être dans une méthode? – physicalattraction

+0

J'ai oublié d'écrire la signature de la méthode :) –

+0

Je ne comprends toujours pas alors. Bien sûr, la chaîne 'shoe' est un exemple, et ne devrait pas être codée en dur. Ai-je accès dans cette méthode à 'self.code' etc.? – physicalattraction

0

1)

try: 
    //somthing 
except IntegrityError as e: 
    print("integrity") 
except Exception as e: 
    print(e)` 

2) Check it

record=Record(type=type_article_structure, 
        code='shoe', 
        group=None) 
record.save()