【问题标题】:Django profile model : Strange Error : Extending Auth User ModelDjango 配置文件模型:奇怪的错误:扩展 Auth 用户模型
【发布时间】:2017-06-18 08:53:30
【问题描述】:

由于 OneToOne 字段导致无法解释的结果(我想)

我的问题见底部

终端输出:

In [21]: profile = User.objects.get(email='jlennon@beatles.com')
In [22]: profile
Out[22]: <User: jlennon@beatles.com>

In [23]: profile = User.objects.get(email='jlennon@beatles.com').profile

In [24]: profile
Out[24]: <Users: ExampleUser1>
In [25]: profile = User.objects.get(id=2).profile

In [26]: profile
Out[26]: <Users: ExampleUser1>

In [27]: User.objects.get(id=2)
Out[27]: <User: jlennon@beatles.com>

In [28]: User.objects.get(id=4)
Out[28]: <User: ExampleUser1>

models.py:

class Users(models.Model):
    user = models.OneToOneField(User, related_name='profile')
    user_Id = models.BigAutoField(primary_key=True)
    user_name = models.CharField(max_length=25)
    user_fname = models.CharField(max_length=40, blank=True, null=True)
    user_lname = models.CharField(max_length=40, blank=True, null=True)
    user_email = models.CharField(max_length=60)
    user_password = models.CharField(max_length=255)
    joining_date = models.DateTimeField()
    user_dob = models.DateField()
    user_country = models.CharField(max_length=3, blank=True, null=True)
    user_gender = models.CharField(max_length=1)
    user_pic = models.CharField(max_length=255, blank=True, null=True)
    user_about = models.CharField(max_length=512, blank=True, null=True)

    class Meta:
        verbose_name = 'Users'
        verbose_name_plural = 'Users'
        managed = False
        db_table = 'tbl_users'

    def __unicode__(self):
        return self.user_name

    def __str__(self):
        return self.user_name

settings.py

AUTH_PROFILE_MODULE = 'myWebsite.Users'

我的数据库:

mysql> select id, username, email from auth_user where id=1 or id=2 or id=4;
+----+---------------------+---------------------+
| id | username            | email               |
+----+---------------------+---------------------+
|  1 | admin               | admin@admin.com     |
|  2 | jlennon@beatles.com | jlennon@beatles.com |
|  4 | ExampleUser1        | user1@example.com   |
+----+---------------------+---------------------+
3 rows in set (0.00 sec)

我的用户表 (tbl_users):

+---------+--------------+---------------------------+
| user_id | user_name    | user_email                |
+---------+--------------+---------------------------+
|       2 | ExampleUser1 | user1@example.com         |
|       3 | Crazy        | crazy@crazy.com           |
+---------+--------------+---------------------------+
2 rows in set (0.00 sec)

我认为由于我在 tbl_users 中没有用户,因此我可能会得到错误的输出。我说的对吗??

OneToOneField , 如何在我的应用程序models.py 中将User 表从django.contrib.auth.mmodels 链接到Users

我认为上述问题的答案可能会让我清楚我应该如何继续制作个人资料模型。

tbl_users 表来自一个旧的 PHP 项目,我不想放弃它,这就是为什么它的模型中仍然有 user_password 字段(因为它已使用inspectdb

但是,我会在注册时开始创建配置文件,因为我在某处阅读了有关制作的内容,我想我不必担心这个问题,因为这样我就会为每个配置文件创建配置文件对象。

但我仍然想知道如何在当前情况下纠正以及我做错了什么


#编辑:#

建议更改的新 Users

class Users(models.Model):
    user = models.OneToOneField(User, related_name='profile')
    user_Id = models.IntegerField()
    user_name = models.CharField(max_length=25)
    user_fname = models.CharField(max_length=40, blank=True, null=True)
    user_lname = models.CharField(max_length=40, blank=True, null=True)
    user_email = models.CharField(primary_key=True, max_length=60)
    user_password = models.CharField(max_length=255)
    joining_date = models.DateTimeField()
    user_dob = models.DateField()
    user_country = CountryField()
    user_gender = models.CharField(max_length=1)
    user_pic = models.CharField(max_length=255, blank=True, null=True)
    user_about = models.CharField(max_length=512, blank=True, null=True)

    class Meta:
        verbose_name = 'Users'
        verbose_name_plural = 'Users'
        managed = False
        db_table = 'tbl_users'

    def __unicode__(self):
        return self.user_name

    def __str__(self):
        return self.user_name

MySQL 表说明

mysql> desc tbl_users;
+---------------+--------------+------+-----+------------------------------+-------+
| Field         | Type         | Null | Key | Default                      | Extra |
+---------------+--------------+------+-----+------------------------------+-------+
| user_id       | int(11)      | NO   |     | NULL                         |       |
| user_name     | varchar(25)  | NO   |     | NULL                         |       |
| user_fname    | varchar(40)  | YES  |     | NULL                         |       |
| user_lname    | varchar(40)  | YES  |     | NULL                         |       |
| user_email    | varchar(60)  | NO   | PRI | NULL                         |       |
| user_password | varchar(255) | NO   |     | NULL                         |       |
| joining_date  | datetime     | NO   |     | NULL                         |       |
| user_dob      | date         | NO   |     | NULL                         |       |
| user_country  | varchar(3)   | YES  |     | NULL                         |       |
| user_gender   | char(1)      | NO   |     | NULL                         |       |
| user_pic      | char(255)    | YES  |     | ../images/provideAnImage.jpg |       |
| user_about    | varchar(512) | YES  |     | NULL                         |       |
+---------------+--------------+------+-----+------------------------------+-------+
12 rows in set (0.00 sec)

但我得到的输出仍然是:

In [4]: User.objects.get(email='user1@example.com').profile
Out[4]: <Users: ExampleUser3>
In [5]: User.objects.get(email='jlennon@beatles.com')
Out[5]: <User: jlennon@beatles.com>

In [6]: User.objects.get(email='jlennon@beatles.com').profile
Out[6]: <Users: ExampleUser1>

##当我试图查看后面的查询时:##

In [7]: User.objects.get(email='jlennon@beatles.com').profile.query
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-7-201041bc7f1c> in <module>()
----> 1 User.objects.get(email='jlennon@beatles.com').profile.query

AttributeError: 'Users' object has no attribute 'query'

In [8]: User.objects.filter(email='jlennon@beatles.com').profile.query
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-8-c4827b8b2ee1> in <module>()
----> 1 User.objects.filter(email='jlennon@beatles.com').profile.query

AttributeError: 'QuerySet' object has no attribute 'profile'

In [9]: User.objects.filter(email='jlennon@beatles.com').query
Out[9]: <django.db.models.sql.query.Query at 0x7fefe8741f90>

所以我找到了替代方法

不过请告诉我一个更好的方法...

In [10]: for conn in connection.queries:
    ...:     print str(conn)+"\n\n"
    ...:     
{u'time': u'0.000', u'sql': u'SELECT @@SQL_AUTO_IS_NULL'}


{u'time': u'0.000', u'sql': u'SELECT VERSION()'}


{u'time': u'0.000', u'sql': u"SELECT `auth_user`.`id`, `auth_user`.`password`, `auth_user`.`last_login`, `auth_user`.`is_superuser`, `auth_user`.`username`, `auth_user`.`first_name`, `auth_user`.`last_name`, `auth_user`.`email`, `auth_user`.`is_staff`, `auth_user`.`is_active`, `auth_user`.`date_joined` FROM `auth_user` WHERE `auth_user`.`email` = 'user2@example.com'"}


{u'time': u'0.000', u'sql': u'SELECT `tbl_users`.`user_id`, `tbl_users`.`user_Id`, `tbl_users`.`user_name`, `tbl_users`.`user_fname`, `tbl_users`.`user_lname`, `tbl_users`.`user_email`, `tbl_users`.`user_password`, `tbl_users`.`joining_date`, `tbl_users`.`user_dob`, `tbl_users`.`user_country`, `tbl_users`.`user_gender`, `tbl_users`.`user_pic`, `tbl_users`.`user_about` FROM `tbl_users` WHERE `tbl_users`.`user_id` = 4'}


{u'time': u'0.000', u'sql': u"SELECT `auth_user`.`id`, `auth_user`.`password`, `auth_user`.`last_login`, `auth_user`.`is_superuser`, `auth_user`.`username`, `auth_user`.`first_name`, `auth_user`.`last_name`, `auth_user`.`email`, `auth_user`.`is_staff`, `auth_user`.`is_active`, `auth_user`.`date_joined` FROM `auth_user` WHERE `auth_user`.`email` = 'jlennon@beatles.com'"}


{u'time': u'0.000', u'sql': u"SELECT `auth_user`.`id`, `auth_user`.`password`, `auth_user`.`last_login`, `auth_user`.`is_superuser`, `auth_user`.`username`, `auth_user`.`first_name`, `auth_user`.`last_name`, `auth_user`.`email`, `auth_user`.`is_staff`, `auth_user`.`is_active`, `auth_user`.`date_joined` FROM `auth_user` WHERE `auth_user`.`email` = 'jlennon@beatles.com'"}


{u'time': u'0.000', u'sql': u'SELECT `tbl_users`.`user_id`, `tbl_users`.`user_Id`, `tbl_users`.`user_name`, `tbl_users`.`user_fname`, `tbl_users`.`user_lname`, `tbl_users`.`user_email`, `tbl_users`.`user_password`, `tbl_users`.`joining_date`, `tbl_users`.`user_dob`, `tbl_users`.`user_country`, `tbl_users`.`user_gender`, `tbl_users`.`user_pic`, `tbl_users`.`user_about` FROM `tbl_users` WHERE `tbl_users`.`user_id` = 2'}


{u'time': u'0.000', u'sql': u"SELECT `auth_user`.`id`, `auth_user`.`password`, `auth_user`.`last_login`, `auth_user`.`is_superuser`, `auth_user`.`username`, `auth_user`.`first_name`, `auth_user`.`last_name`, `auth_user`.`email`, `auth_user`.`is_staff`, `auth_user`.`is_active`, `auth_user`.`date_joined` FROM `auth_user` WHERE `auth_user`.`email` = 'jlennon@beatles.com'"}


{u'time': u'0.000', u'sql': u'SELECT `tbl_users`.`user_id`, `tbl_users`.`user_Id`, `tbl_users`.`user_name`, `tbl_users`.`user_fname`, `tbl_users`.`user_lname`, `tbl_users`.`user_email`, `tbl_users`.`user_password`, `tbl_users`.`joining_date`, `tbl_users`.`user_dob`, `tbl_users`.`user_country`, `tbl_users`.`user_gender`, `tbl_users`.`user_pic`, `tbl_users`.`user_about` FROM `tbl_users` WHERE `tbl_users`.`user_id` = 2'}

【问题讨论】:

  • 我不太清楚到底发生了什么,但我在创建用户时遇到的一个问题是我通过调用'newUser = User.objects.create()'来创建它们,使用查询搜索用户时,我找不到任何用户。当我改为使用“newUser = User.objects.create_user()”时,我可以正确查询它们

标签: python django database django-models relational-database


【解决方案1】:

相信您正在寻找AUTH_USER_MODEL

您已指定AUTH_PROFILE_MODEL,但只要您不指定AUTH_USER_MODEL,Django 将仅使用其内置的用户模型。

编辑:

不幸的是,我无法深入证明,但似乎 django 正在基于主键构建外键关系查询。所以实际上查询

User.objects.get(email='jlennon@beatles.com').profile 

变成类似于:

SELECT tu.id FROM auth_user as au JOIN tbl_users as tu ON au.id=tu.id WHERE au.email='jlennon@beatles.com';

但是由于id=2 for jlennon@beatles.com 当它与您的tbl_users 匹配时,它会获取与id 2 对应的对象,即Aniket。这就是这种奇怪行为的原因。我相信在用户模型中设置 email as PK 应该可以为您解决问题。

如何证明?

您可以尝试运行在控制台中执行的操作并将.query 添加到其中以查找 Django 运行的确切 sql 查询。在这种情况下,例如:User.objects.get(email='jlennon@beatles.com').profile.query,它必须类似于上面的查询。

希望这会有所帮助。还要考虑到AUTH_PROFILE_MODULE 已折旧。鉴于你的情况,我把它留给你。

【讨论】:

  • 这正是我想要避免的,因此我更喜欢 Users 模型中的 OneToOneField
  • 感谢您指出这一点,但它仍然无法正常工作,是的实际上它正在从 auth 获取 id 并从 tbl_users 获取相应的数据我尝试将 PK 更改为电子邮件字段并确实更改了它,但它仍然获取相同的值......我已经应用了迁移,但仍然没有效果 AND 还有一件事您只能在 Queryset 上使用查询i> 对象而不是 Users 对象,profile 将其更改为 User.objects.get(email='jlennon@beatles.com').profile.query AttributeError Traceback (most rece...) User.objects.get(email='jlennon@beatles.com').profile.query
  • @thulasi-ram检查我编辑的问题
猜你喜欢
  • 2017-07-14
  • 1970-01-01
  • 2015-09-21
  • 1970-01-01
  • 2016-10-12
  • 2011-02-28
  • 2013-12-06
  • 2018-01-21
相关资源
最近更新 更多