假设我已正确分类用户模型(CustomUser)(如下所述:http://scottbarnham.com/blog/2008/08/21/extending-the-django-user-model-with-inheritance/)
并安装了评论应用。
在我写的模板中访问评论的用户:
{{comment.user}} # which provides User, not my CustomUser
因此,
{{comment.user.CustomProperty}} #does not work.
我该如何解决它?
答案 0 :(得分:2)
正如你在该帖子的评论中所看到的那样,它仍然存在争议性的讨论,最好的方法是什么。
我也是通过子类化尝试过的,但我遇到了很多问题,而using profiles 对我来说非常适合。
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()
编辑:为什么user_profiles优雅:
我们假设,我们正在编写一个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)
....
....
这导致
现在让我们用user_profiles
来做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()
结果:
这可能会导致模板中的语法更加含糊,但我们可以在views / template_tags中自由选择一些快捷方式,或者使用{% with ... %}
来根据需要调整它。
答案 1 :(得分:2)
来自ForeignKey
的{{1}}是django的内置comments.Comment
对象,因此查询User
会为您提供父对象(即:comment.user
}模型)。但是,django继承确实提供了从超类获取子类版本的方法:
User
然后允许你这样做:
{{ comment.user.customeruser }}
我碰巧认为这是Django继承实现中的一个弱点,因为它并不能完全反映Python中对象继承所期望的行为,但至少有一种解决方法。由于我很难急于提交我的正确行为版本的补丁,我不能抱怨: - )
我同意Carl Meyer的观点:在不改变父模型的db表的情况下自动获取子类可能会很昂贵,并且从父类查询返回子类的实例将与Django承诺查询集返回模型不一致在哪个查询集上运行。
然而,我仍然在实践中发现,Django的继承有时会导致一些尴尬的额外步骤。从0.91开始使用Django,并且知道解决对象关系映射问题的所有不同策略都有权衡,我很高兴现在在Django中继承,并且觉得当前的实现非常好...所以我想讨厌我原来的答案被认为是对项目的轻微反对。因此,我想我会编辑这个答案,链接到Carl自己在解决方案上提供的答案,如果你不知道子类是什么类型的话:How do I access the child classes of an object in Django without knowing the name of the child class?。他在那里提供了使用ContentType框架的建议。还有一些间接涉及,但工具包中有一个很好的,可推广的选项。
答案 2 :(得分:1)
我认为没有办法绕过它,因为如你所说,comment.user
是User
,而不是CustomUser
。
请参阅http://docs.djangoproject.com/en/dev/topics/db/models/#proxy-models:
QUERYSS仍然返回要求的型号
每当你查询User对象时,就没有办法让Django返回一个MyUser对象。 User对象的查询集将返回这些类型的对象。代理对象的重点是依赖于原始用户的代码将使用这些代码,并且您自己的代码可以使用您包含的扩展(无论如何其他代码都不依赖)。它不是用你自己创造的东西替换用户(或任何其他)模型的方法。
也许在这种情况下,使用UserProfile
的旧方式会是更好的选择吗?
对不起,如果我帮不了多。