Я совершенно не понимаю, почему _meta.local_fields возвращает больше полей, чем содержит таблица базы данных. Модель User наследуется от 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)
На странице ошибки Django это оператор SQL, который генерирует ошибку: Значение исключения: (1110, «Столбец» о «указан дважды»)
'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)'
Кажется, что этот оператор SQL создается путем итерации по User._meta.local_fields.
Я не понимаю, почему _meta.local_fields не соответствует фактической схеме таблицы пользователя.
$ 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>]
Дополнительные поля к модели добавляются следующим образом:
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))
Я думаю, вполне возможно, что метод .add_to_class может быть частью этой проблемы.