Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/video/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
django中的自定义用户类是否中断应用程序?_Django_Authentication_Django Models - Fatal编程技术网

django中的自定义用户类是否中断应用程序?

django中的自定义用户类是否中断应用程序?,django,authentication,django-models,Django,Authentication,Django Models,假设我已经正确地对用户模型(CustomUser)进行了子类化(如下所述:) 并安装了评论应用程序 要访问模板中注释的用户,请执行以下操作: {{comment.user}} # which provides User, not my CustomUser 因此 {{comment.user.CustomProperty}} #does not work. 我怎样才能解决它呢?我认为没有办法解决它,因为正如你所说,注释。用户是用户,而不是自定义用户 见: 查询集仍然返回请求的模型 无论何时查

假设我已经正确地对用户模型(CustomUser)进行了子类化(如下所述:)

并安装了评论应用程序

要访问模板中注释的用户,请执行以下操作:

{{comment.user}} # which provides User, not my CustomUser
因此

{{comment.user.CustomProperty}} #does not work.

我怎样才能解决它呢?

我认为没有办法解决它,因为正如你所说,
注释。用户
用户
,而不是
自定义用户

见:

查询集仍然返回请求的模型
无论何时查询用户对象,Django都无法返回(比如)MyUser对象。用户对象的查询集将返回这些类型的对象。代理对象的全部要点是依赖于原始用户的代码将使用这些对象,并且您自己的代码可以使用您包含的扩展(其他代码无论如何都不依赖这些扩展)。这不是一种用你自己创造的东西来替代用户(或任何其他)模型的方法

在这种情况下,使用
UserProfile
的旧方法可能是更好的选择


如果我帮不上什么忙,很抱歉。

正如你在那篇文章的评论中所看到的,它仍然是有争议的讨论,什么是最好的方式

我也尝试过子类化,但我遇到了很多问题,而这对我来说是完美的

class IRCUser(models.Model):
    user        = models.ForeignKey(User, unique=True)
    name        = models.CharField(max_length=100, blank= True, null = True )
    friends     = models.ManyToManyField("IRCUser", blank= True, null = True)
    dataRecieved= models.BooleanField(default=False)
创建IRCUser的工作原理如下:

>>> IRCUser(user = User.objects.get(username='Kermit')).save()
编辑:为什么用户配置文件优雅:

让我们假设,我们正在编写一个webapp,它将作为一个多协议聊天。用户可以在ICQ、MSN、Jabber、FaceBook、Google Talk等网站上提供自己的账户

我们可以通过继承自由创建一个自定义用户类,该类将保存所有附加信息

class CustomUser(User):
    irc_username = models.CharField(blank=True, null=True)
    irc_password = models.PasswordField(blank=True, null=True)
    msn_username = models.CharField(blank=True, null=True)
    msn_password = models.PasswordField(blank=True, null=True)
    fb_username = models.CharField(blank=True, null=True)
    fb_password = models.PasswordField(blank=True, null=True)
    gt_username = models.CharField(blank=True, null=True)
    gt_password = models.PasswordField(blank=True, null=True)
    ....
    ....
这导致了

  • 包含大量零值的数据行
  • 棘手的假设验证
  • 不可能在同一服务中拥有多个帐户
现在让我们用用户_配置文件来做

class IRCProfile(models.Model):
    user = models.ForeignKey(User, unique=True, related_name='ircprofile')
    username = models.CharField()
    password = models.PasswordField()

class MSNProfile(models.Model):
    user = models.ForeignKey(User, unique=True, related_name='msnprofile')
    username = models.CharField()
    password = models.PasswordField()

class FBProfile(models.Model):
    user = models.ForeignKey(User, unique=True, related_name='fbprofile')
    username = models.CharField()
    password = models.PasswordField()
结果是:

  • 用户配置文件可以在需要时创建
  • 数据库没有被零值淹没
  • n相同类型的配置文件可以分配给一个用户
  • 验证很容易

这可能会导致模板中的语法更加晦涩,但我们可以在视图/模板标签中自由设置一些快捷方式,或者使用
{%with…%}
来根据需要对其进行调味。

来自
注释的
外键
。注释
是django的内置
用户
对象,因此,查询
comment.user
将为您提供父对象(即:基本
user
模型)。但是,django继承确实提供了一种从超类获取子类版本的方法:

{{ comment.user.customeruser }}
这将允许您执行以下操作:

{{ comment.user.customeruser.customproperty }}
我碰巧认为这是Django的继承实现中的一个弱点,因为它并不完全反映您通常期望从Python中的对象继承中获得的行为,但至少有一个解决方法。由于我几乎没有急于提交一个带有我的正确行为版本的补丁,我不能抱怨:-)


我同意Carl Meyer的评论:在不改变父模型的db表的情况下自动获取子类可能代价高昂,并且从父类查询返回子类的实例与Django关于queryset返回运行queryset的模型的承诺不一致

然而,我仍然发现在实践中,Django的继承有时会导致一些尴尬的额外步骤。从0.91开始使用Django,并且知道解决对象关系映射问题的所有不同策略都有折衷之处,我很高兴现在在Django中实现了继承,并且觉得当前的实现非常出色。。。所以我不希望我最初的回答被理解为对这个项目的轻蔑


因此,我想我会编辑这个答案,以链接到Carl自己在解决方案中提供的答案,如果您不知道子类是什么类型:。他在那里提供了使用ContentType框架的建议。仍然涉及一些间接操作,但这是工具箱中一个好的、可推广的选项。

我使用了好的旧用户配置文件,但当用户配置文件本身有多对多关系(如朋友)时,事情变得不雅观了。看看这个,这不是很“可爱”吗?:friend=my_user.get_profile()。跟踪了_用户[0]。user——因此,我对user进行了子类化;但现在看来有些应用程序对我来说是不可用的。我可以肯定地看到它会很快变得一团糟!正如我在Arnaud的帖子上评论的那样,我不喜欢userprofile本身有多对多关系的情况。用户和用户之间的关系是userprofile和userprofile之间的关系。不优雅的IMO。请参见我的编辑,以获取一个示例,为什么用户_配置文件可以非常优雅这确实没有“反映出您期望从Python中的对象继承中获得的行为”,但有很好的理由可以实现它,我想如果你尝试写一个补丁,你会发现:-)我假设你想要的行为是让一个对象自动成为“叶”子类;问题在于,对于需要多个昂贵查询才能计算出的大型继承树。或者您必须在父模型上存储类型信息,但是必须修改父模型会导致许多继承用例的死亡。Carl,这是一个很好的补充信息。我在另一个问题的ContentTypes框架的基础上添加了一个链接到您的一个答案。回答得好。我同意Django的继承会导致“尴尬的额外步骤”,只是尴尬是问题域的固有特性,而不是特定的实现。将对象继承映射到关系数据库是一件很麻烦的事情,无论您如何分割它。