Python Django代理模型和其他模型字段?
我正在写一个Django应用程序,它的工作原理就像一份报纸。我有文章,然后我有在特定上下文中出现的这些文章的定制版本。因此,我可以在报纸的头版刊登一篇文章的版本,该文章的原始标题有一个较短的版本。因此,我:Python Django代理模型和其他模型字段?,python,django,design-patterns,model,proxy,Python,Django,Design Patterns,Model,Proxy,我正在写一个Django应用程序,它的工作原理就像一份报纸。我有文章,然后我有在特定上下文中出现的这些文章的定制版本。因此,我可以在报纸的头版刊登一篇文章的版本,该文章的原始标题有一个较短的版本。因此,我: class Article(models.Model): """ A newspaper article with lots of fields """ title = models.CharField(max_le
class Article(models.Model):
""" A newspaper article with lots of fields """
title = models.CharField(max_length=255)
content = models.CharField(max_length=255)
# Lots of fields...
我想要一个CustomArticle对象,它是文章的代理,但有一个可选的标题:
class CustomArticle(Article):
""" An alternate version of a article """
alternate_title = models.CharField(max_length=255)
@property
def title(self):
""" use the alternate title if there is one "
if self.custom_title:
return self.alternate_title
else:
return self.title
class Meta:
proxy = True
# Other fields and methods
很遗憾,我无法向代理添加新字段:
>>TypeError:包含代理模型“CustomArticle”不允许的模型字段的抽象基类
所以,我可以这样做:
class CustomArticle(models.Model):
# Other methods...
original = models.ForeignKey('Article')
def __getattr__(self, name):
if hasattr(self.original):
return getattr(self.original, name)
else:
return super(self, CustomArticle).__getattr__(name)
class CustomArticle(models.Model):
# Other methods...
original = models.ForeignKey('Article')
def __getattr__(self, name):
return getattr(self.original, name)
但不幸的是,
\uuuu getattr\uuuu
似乎不适用于Django模型。Article类中的字段可能会更改,因此为CustomArticle中的每个字段创建@property
方法是不切实际的。做这件事的正确方法是什么?让CustomArticle成为Article的子类怎么样?Django模型确实支持继承!看一看:试试这样的方法:
class CustomArticle(models.Model):
# Other methods...
original = models.ForeignKey('Article')
def __getattr__(self, name):
if hasattr(self.original):
return getattr(self.original, name)
else:
return super(self, CustomArticle).__getattr__(name)
class CustomArticle(models.Model):
# Other methods...
original = models.ForeignKey('Article')
def __getattr__(self, name):
return getattr(self.original, name)
看起来这可能适用于
\uuu getattr\uuu
:
def __getattr__(self, key):
if key not in ('original', '_ original_cache'):
return getattr(self.original, key)
raise AttributeError("'%s' object has no attribute '%s'" % (self.__class__.__name__, key))
我已经考虑过这样做,但我不确定如何将CustomArticle连接到特定的文章,使其ptr_id始终指向数据库中的现有文章。django将创建一个从子模型到父模型的OneToOneField(一种ForeignKey)。这意味着您将在该字段上获得通常的引用完整性约束。如果您正在使用django,您还应该验证,假设您需要这样的功能,django将允许您从已经存在的文章实例创建CustomArticle(就您的问题的域而言,它对应于将文章转换为CustomArticle的可能性)工作流程如下:作者创作一篇文章。稍后,编辑可以从先前存在的文章中创建一个或多个CustomArticles,以便在不同的上下文中使用。我在父/子关系方面的经验是,Django不允许我从现有文章创建CustomArticle。“一个或多个”意味着您不能让CustomArticle使用表继承。你需要用多对一的关系手动处理这个问题。我试图实现的工作流程说明:作者创建一篇文章。之后,编辑可以从先前存在的文章中创建一篇或多篇自定义文章,用于不同的上下文(例如,frontpage的标题版本、其他地方的标注版本等),这些文章似乎90%的时间都有效,但仍有一些情况似乎会导致它进入无限循环并中断(特别是在Django管理界面中)。对于条件查找,这可以避免递归。