2010-04-14 46 views
3

这与this question中提出的问题有些相关,但我试图用抽象基类来做到这一点。从Django中的其他模型填充模型?

对于这个例子的目的,让使用这些模型:

class Comic(models.Model): 
    name = models.CharField(max_length=20) 
    desc = models.CharField(max_length=100) 
    volume = models.IntegerField() 
    ... <50 other things that make up a Comic> 

    class Meta: 
     abstract = True 

class InkedComic(Comic): 
    lines = models.IntegerField() 

class ColoredComic(Comic): 
    colored = models.BooleanField(default=False) 

在视图中可以说我们得到,因为示踪剂的InkedComic id参考,犯错我的意思是,着墨完成绘制线条和它的时间添加颜色。一旦视图添加了我们想要将ColoredComic保存到数据库的所有颜色。

显然,我们可以做

inked = InkedComic.object.get(pk=ink_id) 
colored = ColoredComic() 
colored.name = inked.name 
etc, etc. 

但实际上它会是不错的事情:

colored = ColoredComic(inked_comic=inked) 
colored.colored = True 
colored.save() 

我试图做

class ColoredComic(Comic): 
    colored = models.BooleanField(default=False) 

    def __init__(self, inked_comic = False, *args, **kwargs): 
     super(ColoredComic, self).__init__(*args, **kwargs) 
     if inked_comic: 
      self.__dict__.update(inked_comic.__dict__) 
      self.__dict__.update({'id': None}) # Remove pk field value 

但事实证明了ColoredComic.objects.get(pk=1)通话将pk粘贴到inked_comic关键字中,这显然不是意图。 (并且实际上导致int没有dict例外)

我的大脑在这个时候被炸,我是否错过了某些明显的东西,或者是否有更好的方法来做到这一点?

回答

3

如何处理这个类的静态方法?

colored = ColoredComic.create_from_Inked(pk=ink_id) 
colored.colored = True 
colored.save() 

未经检验的事,但这种效果(使用你的代码从上面)

class ColoredComic(Comic): 
    colored = models.BooleanField(default=False) 

    @staticmethod 
    def create_from_Inked(**kwargs): 
     inked = InkedComic.objects.get(**kwargs) 
     if inked: 
      colored = ColoredComic.objects.create() 
      colored.__dict__.update(inked.__dict__) 
      colored.__dict__.update({'id': None}) # Remove pk field value 
      return colored 
     else: 
      # or throw an exception... 
      return None 
+0

测试这一点,我唯一需要改变 ColoredComic.objects.create()为ColoredComic(),因为我只想在该点处理该模型的本地副本(在保存之前需要更多业务逻辑)。 我现在可以回去工作了!谢谢! – 2010-04-14 21:49:44

0

对于简单的情况下,这将工作:

inked = InkedComic.object.get(pk=ink_id) 
inked.__class__ = ColoredComic 
inked.colored = True 
inked.save() 
+1

我实际上是从这样的事情开始的,但是如果你像这样改变类,那么你并没有在着墨项目上得到所有的ColoredComic属性,所以save()失败了。在这个例子中,通过执行inked.colored = True来解决这个问题,但随着子类属性数量的增长,这变得非常痛苦。 (我的实际问题有六打额外attrs,其中大多数是默认或可选) 但是,对于这个简单的例子,事实上工作:) – 2010-04-14 22:06:03