Opened 14 years ago

Closed 14 years ago

#13777 closed (worksforme)

problems using **kwargs to create an instance of a model with an AutoField primary key

Reported by: seth_a Owned by: nobody
Component: Database layer (models, ORM) Version: 1.2
Severity: Keywords: **kwargs, AutoField
Cc: Triage Stage: Unreviewed
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

I've found that if you create a simple model with an AutoField for a primary key, even the default one, like:

from django import models

class simple(models.Model):
    data = models.CharField()

creating and saving an instance with:

temp = simple(data="example")
temp.save()

causes no problems. If you use kwargs, however:

temp = simple(**{'data':'example'})
temp.save()

then django never defines the Autofield, so when _get_pk_val is called in django/trunk/django/db/models/base.py, its getattr call never finds the field id (or whatever you named it, I tested with explicitly defining an AutoField named blah).

The solution to this is to change _get_pk_val from:

    def _get_pk_val(self, meta=None):
        if not meta:
            meta = self._meta
        return getattr(self, meta.pk.attname)

to:

    def _get_pk_val(self, meta=None):
        if not meta:
            meta = self._meta
        try:
            return getattr(self, meta.pk.attname)
        except AttributeError:
            return None

As None was what this function was supposed to return when the primary key did not exist, the rest of the calling function can now do the right thing and create the AutoField, which I've tested and few times with both the default AutoField and an explicitly defined AutoField primary key, and things seem to work.

There may have been a way to handle this earlier in the code when kwargs was checked, but this was the easiest fix.

And sorry for not having an svn diff! I don't have the development code checked out, and this is my first patch submission.

Also, I've noticed that the code looks the same in the dev version. Perhaps it has the same problem.

Change History (1)

comment:1 by Russell Keith-Magee, 14 years ago

Resolution: worksforme
Status: newclosed

I can't reproduce this. Logically, it doesn't make much sense, either: Klass(data=foo) and Klass({'data':foo}) are identical at the language parsing level, and neither should have any effect on the metaclass (which is where the class it constructed), since you're dealing with the init method when you create an instance.

I suspect you have some other error of usage; please follow this up on django-users.

Also, as a minor stylistic thing: According to PEP8, class names should be capitalized (Simple, not simple).

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