Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django CharField To String

I'm building a tagging system in Django and would like to allow spaces and other characters in the tag name for display but filter them out and use lower case when matching names etc.

To that end I have added a field to my Tag model as so:

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

However I am running into a problem, the CharField is not a string and I cannot for the life of me find out how to convert it to one!

like image 827
DavidM Avatar asked Nov 23 '09 11:11

DavidM


People also ask

What is CharField in Django?

CharField in Django Forms is a string field, for small- to large-sized strings. It is used for taking text inputs from the user. The default widget for this input is TextInput.

What is the difference between CharField and TextField in Django?

CharField has max_length of 255 characters while TextField can hold more than 255 characters. Use TextField when you have a large string as input. It is good to know that when the max_length parameter is passed into a TextField it passes the length validation to the TextArea widget.

What is the max length of CharField in Django?

If a charfield is unique, then its max_length is 255 characters. Otherwise, its max_length on MySQL varchar, 65535 characters.

What is AutoField in Django?

According to documentation, An AutoField is an IntegerField that automatically increments according to available IDs. One usually won't need to use this directly because a primary key field will automatically be added to your model if you don't specify otherwise.


3 Answers

You're defining a class there so name is not a string it's a Django Field.

Additionally, converting name to matchname at the class level doesn't make any sense. You should be doing this on the instance.

You could add a method to your class to do this:

def get_matchname(self):
    """Returns the match name for a tag"""
    return re.sub("\W+" , "", self.name.lower())
like image 115
Dave Webb Avatar answered Oct 08 '22 22:10

Dave Webb


First you have to define the field as as a CharField to be able to use it for search.

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

And then you can overwrite the save function in the model to populate it like this:

class Tag(models.Model):

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

Or use a signal for doing the same:

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)
like image 39
Ferran Avatar answered Oct 08 '22 21:10

Ferran


You could add a method:

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

And use property decorator:

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

All this will let you to access name field lowercased and with non-word characters stripped. But you won't get it stored in DB. If you want this you'll need to add another CharField and keep name and matchname synchronized.

like image 33
pingw33n Avatar answered Oct 08 '22 21:10

pingw33n