Code

#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

Description

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',
                               blank=True)
    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")
        form.save()

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.

Attachments (0)

Change History (1)

comment:1 Changed 18 months ago by msoulier

  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset
  • Resolution set to invalid
  • Status changed from new to closed

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

Add Comment

Modify Ticket

Change Properties
<Author field>
Action
as closed
as The resolution will be set. Next status will be 'closed'
The resolution will be deleted. Next status will be 'new'
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.