Django - updating primary key charfield duplicates

2019-07-19 07:17发布

问题:

I have a model with a charfield serving as primary key. While creating an instance (through admin panel) everything is fine and my clean method works ok too. But if I come back to update myfield than not only clean method fails to catch non-numeric characters, but the whole instance is duplicated. One with old myfield value and the new one with altered myfield.

# models.py
class Mymodel(models.Model):
    myfield = models.CharField(primary_key=True, max_length=10)
    ...
    def clean(self):
        if not re.match(r'[0-9]+', self.pesel):
            raise ValidationError('Digits only.', code='invalid')
        super(Mymodel, self).clean()

How can I fix this? I need it to be a primary key and I need it to be editable. And extra issue with this clean not functioning well, I think it may be connected. I'm Django 1.5.5

回答1:

I meant updating an instance through django admin. Changing the value of myfield and clicking save button doesn't change the actual instance but create (duplicating all the other fields) the new one.

This is how django works, from the documentation:

  • If the object’s primary key attribute is set to a value that evaluates to True (i.e., a value other than None or the empty string), Django executes an UPDATE.

  • If the object’s primary key attribute is not set or if the UPDATE didn’t update anything, Django executes an INSERT.

You are getting caught in the second clause. The first time django attempts to do an update, your new primary key value doesn't exist; so django will insert a new record.

Do you need to have it as a primary key or just as a key? Typically a primary key is a unique value; once a record is created (and since you have foreign keys, linked) - you do not modify the primary key otherwise your relationships will break. In fact, most databases will raise an error if you try to do this; as you will have records pointing to a key that doesn't exist.