I'm completely confused about why _meta.local_fields returns more
fields than the database table contains. The User model inherits from
contrib.auth.models.User.


    $ mysql -u user -p database
    Enter password:
    Reading table information for completion of table and column
names
    You can turn off this feature to get a quicker startup with -A

    Welcome to the MySQL monitor.  Commands end with ; or \g.
    Your MySQL connection id is 1240032
    Server version: 5.0.77 Source distribution

    mysql> describe auth_user;
    +--------------------+------------------+------+-----+---------
+----------------+
    | Field              | Type             | Null | Key | Default |
Extra          |
    +--------------------+------------------+------+-----+---------
+----------------+
    | id                 | int(11)          | NO   | PRI | NULL    |
auto_increment |
    | username           | varchar(30)      | NO   | UNI | NULL
|                |
    | first_name         | varchar(30)      | NO   |     | NULL
|                |
    | last_name          | varchar(30)      | NO   |     | NULL
|                |
    | email              | varchar(75)      | NO   |     | NULL
|                |
    | password           | varchar(128)     | NO   |     | NULL
|                |
    | is_staff           | tinyint(1)       | NO   |     | NULL
|                |
    | is_active          | tinyint(1)       | NO   |     | NULL
|                |
    | is_superuser       | tinyint(1)       | NO   |     | NULL
|                |
    | last_login         | datetime         | NO   |     | NULL
|                |
    | date_joined        | datetime         | NO   |     | NULL
|                |
    | email_isvalid      | tinyint(1)       | NO   |     | NULL
|                |
    | email_key          | varchar(16)      | YES  |     | NULL
|                |
    | reputation         | int(10) unsigned | NO   |     | NULL
|                |
    | gravatar           | varchar(32)      | NO   |     | NULL
|                |
    | gold               | smallint(6)      | NO   |     | NULL
|                |
    | silver             | smallint(6)      | NO   |     | NULL
|                |
    | bronze             | smallint(6)      | NO   |     | NULL
|                |
    | questions_per_page | smallint(6)      | NO   |     | NULL
|                |
    | last_seen          | datetime         | NO   |     | NULL
|                |
    | real_name          | varchar(100)     | NO   |     | NULL
|                |
    | website            | varchar(200)     | NO   |     | NULL
|                |
    | location           | varchar(100)     | NO   |     | NULL
|                |
    | date_of_birth      | date             | YES  |     | NULL
|                |
    | about              | longtext         | NO   |     | NULL
|                |
    +--------------------+------------------+------+-----+---------
+----------------+
    25 rows in set (0.00 sec)


>From the Django error page, this is the SQL statement that generates
the error:   Exception Value: (1110, "Column 'about' specified twice")

    'INSERT INTO `auth_user` (`username`, `first_name`, `last_name`,
`email`, `password`, `is_staff`, `is_active`, `is_superuser`,
`last_login`, `date_joined`,     `email_isvalid`, `email_key`,
`reputation`, `gravatar`, `gold`, `silver`, `bronze`,
`questions_per_page`, `last_seen`, `real_name`, `website`, `location`,
`date_of_birth`, `about`, `email_isvalid`, `email_key`, `reputation`,
`gravatar`, `gold`, `silver`, `bronze`, `questions_per_page`,
`last_seen`, `real_name`, `website`, `location`, `date_of_birth`,
`about`) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s,
%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s,
%s, %s, %s, %s, %s, %s, %s, %s)'

This SQL statement seems to be generated by iterating over
User._meta.local_fields.
I don't understand why _meta.local_fields doesn't match the actual
User table schema.

    $ python2.5 manage.py shell
    Python 2.5.4 (r254:67916, Aug  5 2009, 12:42:40)
    [GCC 4.1.2 20080704 (Red Hat 4.1.2-44)] on linux2
    Type "help", "copyright", "credits" or "license" for more
information.
    (InteractiveConsole)
    >>> from forum.models import User
    >>> len(User._meta.local_fields)
    39
    >>> import pprint
    >>> pprint.pprint(User._meta.local_fields)
    [<django.db.models.fields.AutoField object at 0x852c80c>,
     <django.db.models.fields.CharField object at 0x8528c4c>,
     <django.db.models.fields.CharField object at 0x8528cac>,
     <django.db.models.fields.CharField object at 0x8528d0c>,
     <django.db.models.fields.EmailField object at 0x8528d6c>,
     <django.db.models.fields.CharField object at 0x8528e2c>,
     <django.db.models.fields.BooleanField object at 0x8528ecc>,
     <django.db.models.fields.BooleanField object at 0x8528f6c>,
     <django.db.models.fields.BooleanField object at 0x852c02c>,
     <django.db.models.fields.DateTimeField object at 0x852c0ac>,
     <django.db.models.fields.DateTimeField object at 0x852c0ec>,
     # here is where customizations to User begin.
     <django.db.models.fields.BooleanField object at 0x861744c>,
     <django.db.models.fields.CharField object at 0x861732c>,
     <django.db.models.fields.PositiveIntegerField object at
0x861746c>,
     <django.db.models.fields.CharField object at 0x861748c>,
     <django.db.models.fields.SmallIntegerField object at
0x861784c>,
     <django.db.models.fields.SmallIntegerField object at
0x86178ec>,
     <django.db.models.fields.SmallIntegerField object at
0x861792c>,
     <django.db.models.fields.SmallIntegerField object at
0x861796c>,
     <django.db.models.fields.DateTimeField object at 0x861798c>,
     <django.db.models.fields.CharField object at 0x86179cc>,
     <django.db.models.fields.URLField object at 0x8617a0c>,
     <django.db.models.fields.CharField object at 0x8617a4c>,
     <django.db.models.fields.DateField object at 0x8617a8c>,
     <django.db.models.fields.TextField object at 0x8617acc>,
     # this seems to be a duplicate of the fields added to User
     <django.db.models.fields.BooleanField object at 0x862ab2c>,
     <django.db.models.fields.CharField object at 0x862a4ac>,
     <django.db.models.fields.PositiveIntegerField object at
0x862ab6c>,
     <django.db.models.fields.CharField object at 0x862f6cc>,
     <django.db.models.fields.SmallIntegerField object at
0x861782c>,
     <django.db.models.fields.SmallIntegerField object at
0x862fa2c>,
     <django.db.models.fields.SmallIntegerField object at
0x862fa4c>,
     <django.db.models.fields.SmallIntegerField object at
0x862fa8c>,
     <django.db.models.fields.DateTimeField object at 0x862faac>,
     <django.db.models.fields.CharField object at 0x862faec>,
     <django.db.models.fields.URLField object at 0x862fb2c>,
     <django.db.models.fields.CharField object at 0x862fb6c>,
     <django.db.models.fields.DateField object at 0x862fbac>,
     <django.db.models.fields.TextField object at 0x862fbec>]
>>>

This is how this project customized User:

from django.contrib.auth.models import User

The additional fields to the model are added thusly:

    User.add_to_class('email_isvalid',
models.BooleanField(default=False))
    User.add_to_class('email_key', models.CharField(max_length=16,
null=True))
    User.add_to_class('reputation',
models.PositiveIntegerField(default=1))
    User.add_to_class('gravatar', models.CharField(max_length=32))
    User.add_to_class('email_feeds',
generic.GenericRelation(EmailFeed))
    User.add_to_class('favorite_questions',
models.ManyToManyField(Question, through=FavoriteQuestion,
related_name='favorited_by'))
    User.add_to_class('badges', models.ManyToManyField(Badge,
through=Award, related_name='awarded_to'))
    User.add_to_class('gold', models.SmallIntegerField(default=0))
    User.add_to_class('silver', models.SmallIntegerField(default=0))
    User.add_to_class('bronze', models.SmallIntegerField(default=0))
    User.add_to_class('questions_per_page',
models.SmallIntegerField(choices=QUESTIONS_PER_PAGE_CHOICES,
default=10))
    User.add_to_class('last_seen',
models.DateTimeField(default=datetime.datetime.now))
    User.add_to_class('real_name', models.CharField(max_length=100,
blank=True))
    User.add_to_class('website', models.URLField(max_length=200,
blank=True))
    User.add_to_class('location', models.CharField(max_length=100,
blank=True))
    User.add_to_class('date_of_birth', models.DateField(null=True,
blank=True))
    User.add_to_class('about', models.TextField(blank=True))


I wonder if the User.add_to_class would be interpreted twice. This is
an open source project, CNPROG @ Github. I did not create it.

It does seem it would have been better to use UserProfile or to
subclass User. I'll have to refactor this now. The project has no
tests, so I might have to create those first. I did hear there was an
issue with MySQLdb and MySQL interface a while back, but I don't know
the version.

-- 
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To post to this group, send email to django-us...@googlegroups.com.
To unsubscribe from this group, send email to 
django-users+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/django-users?hl=en.

Reply via email to