2010-09-23 8 views
0

Je veux une table qui ne peut avoir qu'un seul enregistrement. Ma solution actuelle est:Meilleure façon de créer une table Singleton dans Django/MySQL

class HitchingPost(models.Model): 
    SINGLETON_CHOICES = (('S', 'Singleton'),) 
    singleton = models.CharField(max_length=1, choices=SINGLETON_CHOICES, unique=True, null=False, default='S'); 
    value = models.IntegerField() 

    def __unicode__(self): 
     return u"HitchingPost" # only ever one record 

C'est un peu laid, et ne l'applique pas la contrainte au niveau MySQL.

Existe-t-il une meilleure solution?

Existe-t-il un type de champ MySQL qui ne peut avoir qu'une valeur (boolean est le plus petit que j'ai trouvé, ayant deux possibilités)? Un chiffre de base 0 est le plus proche de l'expression du concept.

Existe-t-il un nom mathématique pour une telle chose?

Merci,

Chris.

P.S. SQL généré est:

CREATE TABLE `appname_hitchingpost` (
    `id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY, 
    `singleton` varchar(1) NOT NULL UNIQUE, 
    `value` integer NOT NULL 
) 
; 
+0

'' Y at-il un nom mathématique pour une telle chose? '' - une constante? –

+0

Il impose une contrainte au niveau MySQL. Essayez par exemple 'HitchingPost.objects.create (valeur = 12)' suivi par ex. 'HitchingPost.objects.create (valeur = 13)'. Si vous n'obtenez pas IntegrityError, vous avez un problème plus large. –

+0

@Tomasz - oui, il renforce l'intégrité de la couche Django, mais la table MySQL n'a pas de contraintes similaires. Une application non-Django pourrait insérer valeur = 13 sans problème. Je vais creuser le SQL qu'il crée, si vous êtes intéressé. – fadedbee

Répondre

2

C'est un peu laid, et ne l'applique pas la contrainte au niveau MySQL.

Si vous êtes préoccupé par l'application, vous devriez regarder les méthodes model validation de Django. Vous pouvez écrire un validate_unique personnalisé qui soulèvera un ValidationError si HitchingPost.objects.count() != 0.

class HitchingPost(models.Model): 
    ... 
    def validate_unique(self, exclude = None): 
     from django.core.exceptions import ValidationError, NON_FIELD_ERRORS 
     if HitchingPost.objects.count() != 0: 
      raise ValidationError({NON_FIELD_ERRORS: ["There can be only one!"]}) 

est-il une meilleure solution?

Difficile à dire sans en savoir plus sur votre exigence plus large. Y at-il un type de champ MySQL qui ne peut avoir qu'une seule valeur (boolean est le plus petit que j'ai trouvé, ayant deux possibilités)? Un chiffre de base 0 est le plus proche de l'expression du concept. Vous pouvez essayer un élément unique personnalisé enum. Je n'ai jamais rien essayé de tel, alors prenez mes conseils avec une pincée de sel.

Existe-t-il un nom mathématique pour une telle chose?

Set-once-constant? J'ai inventé ça. En vérité, je n'en ai aucune idée. De meilleures personnes ici vous aideront.

+0

Je viens de mettre en œuvre cette solution et cela a très bien fonctionné, merci! La seule chose que j'ajouterais est que vous pouvez autoriser la création et la mise à jour du premier modèle, vérifier l'absence d'une clé primaire sur le modèle lors de l'enregistrement: 'sinon self.pk et HitchingPost.objects. count()> 0: ... ' – errkk

+0

si HitchingPost.objects.exclude (id = self.id) .count()> 0: permet de mettre à jour self. – un33k

Questions connexes