2009-11-23 8 views
3

Je construis un système de marquage dans Django et je voudrais permettre à des espaces et autres caractères dans le nom de la balise pour l'affichage, mais les filtrer et utiliser les minuscules lorsque les noms correspondant etc.Django CharField à cordes

À cette fin j'ai ajouté un champ à mon modèle Tag comme si:

class Tag(models.Model): 
    name = models.CharField(max_length=200, unique=True) 
    matchname = re.sub("\W+" , "", name.lower()) 

Cependant, je suis en cours d'exécution dans un problème, le CharField est pas une chaîne et je ne peux pas pour la vie de me savoir comment convertir en un !

+2

Argh ... ne peut pas poster une réponse sans obtenir une erreur de serveur :-( –

+1

Avoir un vote à la place alors ;;) – DavidM

Répondre

6

Vous définissez un class là donc name n'est pas une chaîne c'est un Django Field.

En outre, la conversion de name en matchname au niveau de la classe n'a aucun sens. Vous devriez le faire sur l'instance.

Vous pouvez ajouter une méthode à votre classe pour ce faire:

def get_matchname(self): 
    """Returns the match name for a tag""" 
    return re.sub("\W+" , "", self.name.lower()) 
+1

Quelque chose comme 'def matchname (self): return re.sub (" \ W + "," ", self. name.lower()) '(c'est ce que j'allais mettre dans mon réponse, mais aujourd'hui stackoverflow me déteste). –

+0

@Dominic - Était juste en train d'éditer la réponse pour l'ajouter. Je reçois toujours des erreurs de serveur; le site ne cesse de me connecter et sortir ce qui je pense est la source du problème. –

+0

+1 de moi (docstrings dans les exemples de code? Quoi que ce soit ensuite!) –

2

Vous pouvez ajouter une méthode:

class Tag(models.Model): 
    name = models.CharField(max_length=200, unique=True) 
    def get_matchname(self): 
     return re.sub("\W+" , "", name.lower()) 

Et utiliser property décorateur:

class Tag(models.Model): 
    name = models.CharField(max_length=200, unique=True) 
    @property 
    def matchname(self): 
     return re.sub("\W+" , "", name.lower()) 

Tout cela vous permettra d'accéder au champ name en minuscules et aux caractères non-mots supprimés. Mais vous ne l'obtiendrez pas stocké dans DB. Si vous voulez cela, vous devrez ajouter un autre CharField et garder name et matchname synchronisés.

4

Vous devez d'abord définir le champ en tant que champ CharField pour pouvoir l'utiliser pour la recherche.

class Tag(models.Model): 
    name = models.CharField(max_length=200, unique=True) 
    matchname = models.CharField(max_length=200, unique=True) 

Et vous pouvez remplacer la fonction de sauvegarde dans le modèle pour le remplir comme ceci:

class Tag(models.Model): 

    def save(self): 
     self.matchname = re.sub("\W+" , "", self.name.lower()) 
     super(Tag,self).save() 

Ou utiliser un signal pour faire la même chose:

from django.db.models.signals import pre_save 

def populate_matchname(sender,instance,**kwargs): 
    instance.matchname = re.sub("\W+" , "", instance.name.lower()) 

pre_save(populate_matchname,sender=Tag)