Opened 18 years ago

Closed 18 years ago

Last modified 17 years ago

#847 closed defect (invalid)

users.create_user fails if User is subclassed using replaces_module = 'auth.users'

Reported by: EABinGA Owned by: Adrian Holovaty
Component: Metasystem Version:
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

Given the following model:

class User(auth.User):
    class META:
        admin = meta.Admin()
        replaces_module = 'auth.users' 

    foo = meta.URLField(blank=True)

¨django-admin.py sql auth¨ creates the correct output

CREATE TABLE "auth_users" (
    "id" integer NOT NULL PRIMARY KEY,
    "date_joined" datetime NOT NULL,
    "last_login" datetime NOT NULL,
    "is_superuser" bool NOT NULL,
    "is_active" bool NOT NULL,
    "is_staff" bool NOT NULL,
    "password_md5" varchar(32) NOT NULL,
    "email" varchar(75) NOT NULL,
    "last_name" varchar(30) NOT NULL,
    "first_name" varchar(30) NOT NULL,
    "username" varchar(30) NOT NULL UNIQUE,
    "foo" varchar(200) NOT NULL
);

But an attempt to create a superuser with django-admin fails.
A debugging session yields the following:

eric@home[bbs]|1> %pdb
Automatic pdb calling has been turned ON
eric@home[bbs]|2> from django.models.auth import users
eric@home[bbs]|3> users.create_user("foo", "bar@baz.com", "secret")
---------------------------------------------------------------------------
exceptions.AttributeError                            Traceback (most recent call last)

/home/eric/django/bbs/<console>

/usr/lib/python2.4/site-packages/django-1.0.0-py2.4.egg/django/models/auth.py in _module_create_user(username, email, password)
    181         now = datetime.datetime.now()
    182         user = User(None, username, '', '', email.strip().lower(), password_md5, False, True, False, now, now)
--> 183         user.save()
    184         return user
    185

/usr/lib/python2.4/site-packages/django-1.0.0-py2.4.egg/django/utils/functional.py in _curried(*moreargs, **morekwargs)
      2     def _curried(*moreargs, **morekwargs):
----> 3         return args[0](*(args[1:]+moreargs), **dict(kwargs.items() + morekwargs.items()))
      4     return _curried
      5
      6 def lazy(func, *resultclasses):

/usr/lib/python2.4/site-packages/django-1.0.0-py2.4.egg/django/core/meta/__init__.py in method_save(opts, self)
    941         field_names = [db.db.quote_name(f.column) for f in opts.fields if not isinstance(f, AutoField)]
    942         placeholders = ['%s'] * len(field_names)
--> 943         db_values = [f.get_db_prep_save(f.pre_save(getattr(self, f.attname), True)) for f in opts.fields if not isinstance(f, AutoField)]
    944         if opts.order_with_respect_to:
    945             field_names.append(db.db.quote_name('_order'))

AttributeError: 'User' object has no attribute 'foo'
> /usr/lib/python2.4/site-packages/django-1.0.0-py2.4.egg/django/core/meta/__init__.py(943)method_save()
-> db_values = [f.get_db_prep_save(f.pre_save(getattr(self, f.attname), True)) for f in opts.fields if not isinstance(f, AutoField)]


(Pdb) field_names
['"date_joined"', '"last_login"', '"is_superuser"', '"is_active"', '"is_staff"', '"password_md5"', '"email"', '"last_name"', '"first_name"', '"username"', '"foo"']


(Pdb) self.__class__
<class 'django.models.board.User'>

(Pdb) dir(self) # WHERE IS FOO??
['__class__', '__delattr__', '__dict__', '__doc__', '__eq__', '__getattribute__', '__hash__', '__init__', '__metaclass__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__str__', '__weakref__', '_meta', 'add_message', 'check_password', 'date_joined', 'delete', 'email', 'email_user', 'first_name', 'get_absolute_url', 'get_all_permissions', 'get_and_delete_messages', 'get_board_post', 'get_board_post_count', 'get_board_post_list', 'get_board_topic', 'get_board_topic_count', 'get_board_topic_list', 'get_full_name', 'get_group_list', 'get_group_permissions', 'get_message', 'get_message_count', 'get_message_list', 'get_next_by_date_joined', 'get_next_by_last_login', 'get_permission_list', 'get_previous_by_date_joined', 'get_previous_by_last_login', 'get_profile', 'has_module_perms', 'has_perm', 'has_perms', 'id', 'is_active', 'is_anonymous', 'is_staff', 'is_superuser', 'last_login', 'last_name', 'password_md5', 'save', 'set_groups', 'set_password', 'set_user_permissions', 'username']

(Pdb) getattr(self, f.attname)
*** AttributeError: 'User' object has no attribute 'foo'

Change History (2)

comment:1 by Adrian Holovaty, 18 years ago

Resolution: invalid
Status: newclosed

If you do replaces_module = 'auth.users', you're responsible for overriding the create_user module-level function on your own.

comment:2 by EABinGA, 18 years ago

The question that I still have though, is why does self (an instance of my custom user class) in method_save not have an attribute ¨foo¨?

I can see the need to provide my own create_user in some cases, but the ¨foo¨ field in this case is set to blank=true and I would expect it to be filled with an apropriate ¨blank¨ value.

I havent grokked much of the meta framework yet and this (hopefully) will become moot, once I can create a working OneToOne relationship with User. (Which btw. doesnt seem to work properly either)

I will take your word and leave this ticket as closed until I know better ;)

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