5

When I try and save (using the Django standard admin interface) I get the following error...

TypeError at /admin/web/campaign/dc6eb21f-87fa-462f-88af-416cf6be37f6/

get_db_prep_value() got an unexpected keyword argument 'connection'

Could someone explain this to me, why and maybe a possible solution? I'm assuming it is something to do with my custom HibernateBooleanField field.

Full error and details below.

Error

Environment:


Request Method: POST
Request URL: http://127.0.0.1:8000/admin/web/campaign/dc6eb21f-87fa-462f-88af-416cf6be37f6/

Django Version: 1.4.2
Python Version: 2.7.2
Installed Applications:
('django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.sites',
 'django.contrib.flatpages',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'grappelli.dashboard',
 'grappelli',
 'django.contrib.admin',
 'django.contrib.admindocs',
 'web')
Installed Middleware:
('django.middleware.common.CommonMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware')


Traceback:
File "/Library/Python/2.7/site-packages/django/core/handlers/base.py" in get_response
  111.                         response = callback(request, *callback_args, **callback_kwargs)
File "/Library/Python/2.7/site-packages/django/contrib/admin/options.py" in wrapper
  366.                 return self.admin_site.admin_view(view)(*args, **kwargs)
File "/Library/Python/2.7/site-packages/django/utils/decorators.py" in _wrapped_view
  91.                     response = view_func(request, *args, **kwargs)
File "/Library/Python/2.7/site-packages/django/views/decorators/cache.py" in _wrapped_view_func
  89.         response = view_func(request, *args, **kwargs)
File "/Library/Python/2.7/site-packages/django/contrib/admin/sites.py" in inner
  196.             return view(request, *args, **kwargs)
File "/Library/Python/2.7/site-packages/django/utils/decorators.py" in _wrapper
  25.             return bound_func(*args, **kwargs)
File "/Library/Python/2.7/site-packages/django/utils/decorators.py" in _wrapped_view
  91.                     response = view_func(request, *args, **kwargs)
File "/Library/Python/2.7/site-packages/django/utils/decorators.py" in bound_func
  21.                 return func(self, *args2, **kwargs2)
File "/Library/Python/2.7/site-packages/django/db/transaction.py" in inner
  209.                 return func(*args, **kwargs)
File "/Library/Python/2.7/site-packages/django/contrib/admin/options.py" in change_view
  1054.                 self.save_model(request, new_object, form, True)
File "/Library/Python/2.7/site-packages/django/contrib/admin/options.py" in save_model
  709.         obj.save()
File "/Library/Python/2.7/site-packages/django/db/models/base.py" in save
  463.         self.save_base(using=using, force_insert=force_insert, force_update=force_update)
File "/Library/Python/2.7/site-packages/django/db/models/base.py" in save_base
  529.                             rows = manager.using(using).filter(pk=pk_val)._update(values)
File "/Library/Python/2.7/site-packages/django/db/models/query.py" in _update
  560.         return query.get_compiler(self.db).execute_sql(None)
File "/Library/Python/2.7/site-packages/django/db/models/sql/compiler.py" in execute_sql
  986.         cursor = super(SQLUpdateCompiler, self).execute_sql(result_type)
File "/Library/Python/2.7/site-packages/django/db/models/sql/compiler.py" in execute_sql
  808.             sql, params = self.as_sql()
File "/Library/Python/2.7/site-packages/django/db/models/sql/compiler.py" in as_sql
  951.                 val = field.get_db_prep_save(val, connection=self.connection)
File "/Library/Python/2.7/site-packages/django/db/models/fields/__init__.py" in get_db_prep_save
  292.                                       prepared=False)

Exception Type: TypeError at /admin/web/campaign/dc6eb21f-87fa-462f-88af-416cf6be37f6/
Exception Value: get_db_prep_value() got an unexpected keyword argument 'connection'

model

class Campaign(models.Model):
    campaignid = models.CharField(max_length=255, primary_key=True, db_column='campaignID')
    name = models.CharField(max_length=105)
    active = HibernateBooleanField(default=False)
    created = models.DateTimeField()
    modified = models.DateTimeField(null=True, blank=True)
    companyid = models.ForeignKey(Company, null=True, db_column='companyID', blank=True)

    class Meta:
        db_table = u'campaign'


    def __unicode__(self):
        return self.name

class HibernateBooleanField(models.BooleanField):

    __metaclass__ = models.SubfieldBase

    def get_internal_type(self):
        return "HibernateBooleanField"

    def db_type(self):
        return 'bit(1)'

    def to_python(self, value):
        if value in (True, False): return value
        if value in ('t', 'True', '1', '\x01'): return True
        if value in ('f', 'False', '0', '\x00'): return False

    def get_db_prep_value(self, value):
        return 0x01 if value else 0x00
Prometheus
  • 32,405
  • 54
  • 166
  • 302

2 Answers2

9

Yes, that would be a fair assumption. As you can see from the source code, the signature of that method is def get_db_prep_value(self, value, connection, prepared=False), so any subclass needs to either expect the same arguments or take *args, **kwargs.

Daniel Roseman
  • 588,541
  • 66
  • 880
  • 895
8

Daniel Roseman pretty much answered this, but I will state it in another way and use more words so that you hopefully understand. For custom fields in Django 1.4.x, your custom field's get_db_prep_value function MUST NOW ACCEPT 4 parameters. In Django 1.2, the Django developers introduced multiple database support. In Django 1.4.x, the developers REMOVED code that would've allowed your function declaration to work.

So what do you need to do? You need to redefine HibernateBooleanField.get_db_prep_value to accept the extra arguments. Change your get_db_prep_value function like I have below, and it will work :)

def get_db_prep_value(self, value, connection, prepared=False):
    return 0x01 if value else 0x00

Django documentation reference: https://docs.djangoproject.com/en/1.2/howto/custom-model-fields/#django.db.models.Field.get_db_prep_value

rgenito
  • 1,751
  • 13
  • 8