_meta.local_fields如何与数据库中的表模式不匹配?

时间:2010-02-06 16:09:50

标签: python django django-models

我完全混淆了为什么_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与实际的User表架构不匹配。

$ 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方法可能是此问题的一部分。

1 个答案:

答案 0 :(得分:0)

如果您展示与此问题相关的 Django模型,那将会很有帮助。从SQL中的字段名称看,这个模型似乎继承自contrib.auth.models.User,是真的吗?如果是这样,您是否碰巧复制了用户模型中定义的字段名称?

更新:更直言不讳地说,我要求您编辑问题并包含您在models.py文件中声明的特定模型。几乎可以肯定的是,您声明了两个具有相同名称的字段。 auth.models.User中声明的最后一个字段是date_joined所以 about定义应显示在您的模型声明中。

实际上,在仔细检查SQL之后,您不仅有两列名为about的列,而且还有 14 重复的字段名称。有些事情不对。

用Jerry McGuire的话来解释:告诉我模特!: - )

第二次更新(使用1个啤酒障碍(这是好东西!)

我从未以这种方式使用过add_to_class。你为什么选择这条路线而不使用更标准的Django model inheritance技术?或者,因为这是您正在处理的用户,为什么不使用UserProfile。它可能有点笨重,但效果很好。

第三次更新

啊,Domini Nabisco,我的儿子 - 我没有意识到你是从别人那里继承了这个。需要注意的是:因为这改变了Django中的一个基本类(以一种明确的非标准方式),您可能需要在user个文件中查看.py的每个引用。 模板。根据继承项目的大小,这可能是巨大的 PITA,特别是当它缺少测试时。你有没有机会追捕,我的意思是找到负责人并获得更多洞察力?这可能是让事情发挥作用的较短途径。祝你好运!