Opened 4 years ago

Closed 4 years ago

#19228 closed Bug (invalid)

changing primary key contents on ModelForm with sqlite results in noop

Reported by: msoulier@… Owned by: nobody
Component: Database layer (models, ORM) Version: 1.4
Severity: Normal Keywords:
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no


Using Django 1.4.1, when I allow an edit of the column which happens to be the primary key for the model, the resulting save of the ModelForm results in nothing happening. No modification of the existing model, no new model created, no error thrown, nothing.

I expected a new model, since the primary key changed to one that was not in the database. My workaround is to not use a natural, editable primary key, but this seemed worth reporting.

My model:

class McdLoad(models.Model):
    """A model representing an MCD load uploaded to the server, either by the
    UI or by a blade."""
    version = models.CharField(max_length=32, primary_key=True)
    mcdload = models.FileField(upload_to='ftproot',
    fromversions = models.CharField(max_length=4096, default='')
    remove_load = models.BooleanField(default=False)
    def __str__(self):
        return "%s:%s" % (self.version, self.fromversions)
    class Meta:
        db_table = 'mcdloads'

My form

class McdLoadForm(forms.ModelForm):
    VERSIONPAT = re.compile(r'^(\d+\.){3}\d+$')
    class Meta:                
        model = McdLoad
        fields = ('version', 'mcdload', 'fromversions')
    def clean(self):
        cleaned_data = super(McdLoadForm, self).clean()
        version = cleaned_data.get('version', '')
        log.debug("cleaned_data: version is %s" % version)
        if version:
            version = re.sub(r'^\s+|\s+$', '', version)
            if not McdLoadForm.VERSIONPAT.match(version):
                raise forms.ValidationError, \
                    "Bad version, should be 4-digits separated by commas"
            cleaned_data['version'] = version
        fromversions = self.cleaned_data.get('fromversions', '')
        if fromversions:
            fromversions = re.sub(r'\s', '', fromversions)
            for version in fromversions.split(','):
                if not McdLoadForm.VERSIONPAT.match(version):
                    raise forms.ValidationError, \
                        "Bad version, should be 4-digits separated by commas"
            cleaned_data['fromversions'] = fromversions   
        log.debug("clean: returning %s" % cleaned_data)
        return cleaned_data

relevant view code:

mcdload = McdLoad.objects.get(version=version)
if request.method == 'POST':
    form = McdLoadForm(request.POST, instance=mcdload)
    if form.is_valid():
        log.debug("form is valid")

Adding additional debug here shows that the new "version" field is validated and in the form's cleaned_data, right up to the save call. If I capture the result of the save, the resulting model has the new version field. And yet, it does not appear in the db.

Using python-sqlite2 2.6.3 and sqlite 3.6.20 on CentOS Linux 6 with Django 1.4.1 and Python 2.6.6.

Change History (1)

comment:1 Changed 4 years ago by msoulier

Needs documentation: unset
Needs tests: unset
Patch needs improvement: unset
Resolution: invalid
Status: newclosed

Found it, some back-end code that I missed was modifying the database. Sorry to waste your time.

Note: See TracTickets for help on using tickets.
Back to Top