我对Django非常陌生,现在我正在尝试理解抽象模型的使用。假设您正在编写博客服务,并且希望通过身份验证和匿名的用户都能够对博客文章进行评论。
虽然对于经过身份验证的用户来说,场景非常简单(只是有一个引用特定用户的外键),但是当Authors不仅仅是User,而是AnonymousAuthors或RegisteredAuthor的时候,情况就不那么简单了。
这里的直接方法是构建一个类的层次结构:
class Author(models.Model):
class Meta:
abstract = True
class AnonymousAuthor(Author):
name = models.CharField(max_length=128)
def display_name(self):
return self.name
class RegisteredAuthor(Author):
user = models.ForeignKey(User)
def display_name(self):
return self.user.user_name然后可以这样定义BlogPostComment:
class BlogPostComment(models.Model):
author = models.ForeignKey(Author)
...我喜欢这种方法,因为无论作者是谁,只要迭代BlogPostComment的集合并为每个注释调用display_name(),我就可以轻松地构建注释列表。这里唯一的问题是它不起作用。Django说:
AssertionError: ForeignKey cannot define a relation with abstract class Author解决办法是什么?
更新
我知道泛型关系在这里能帮上忙。但这是唯一的解决办法吗?感觉有点过火了。
发布于 2012-08-02 19:31:03
泛型关系是为许多人创建外键的解决方案,与模型不同。通常情况下,如果您有以下继承,则使用继承:
class Animal(models.Model):
...
class Dog(Animal):
...然后以后:
models.ForeignKey(Animal)您也可以将Dog存储为外键,因为Dog是-一个Animal。但是,在抽象类的情况下,这些类不符合设置为外键目标的条件,因为它们不存在。Django的“抽象”模型更接近于“mixin”的定义:它们从未单独实例化过,而是用于组成其他实例化的类。
所以你有三个选择:
Author改为标准模型,而不是抽象模型。然后,您可以创建Author的外键,并传入Author的任何子类。这里的最后一个选择实际上是您最好的选择,因为没有理由有单独的作者表,而唯一的定义差别是它们是注册的还是匿名的。这是对象的状态,而不是不同类型的对象。就像使用类似于BlueCar类的东西是不合适的。您有一个Car类,而"blue“是它的color属性的值。
如果你坚持要不同的模特。然后,您可以使用代理模型。其中,AnonymousAuthor和RegisterAuthor只是Author的别名(它们没有自己的表),但是有了别名,您就可以更改或添加自定义方法,特别是能够指定一个自定义管理器,该管理器可以自动过滤Author以分别返回“匿名”或“注册”类型。
https://stackoverflow.com/questions/11783895
复制相似问题