This is somewhat related to the question posed in this question but I'm trying to do this with an abstract base class.
For the purposes of this example lets use these models:
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 开发者_JAVA技巧= models.BooleanField(default=False)
In the view lets say we get a reference to an InkedComic id
since the tracer, err I mean, inker is done drawing the lines and it's time to add color. Once the view has added all the color we want to save a ColoredComic
to the db.
Obviously we could do
inked = InkedComic.object.get(pk=ink_id)
colored = ColoredComic()
colored.name = inked.name
etc, etc.
But really it'd be nice to do:
colored = ColoredComic(inked_comic=inked)
colored.colored = True
colored.save()
I tried to do
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
but it turns out the ColoredComic.objects.get(pk=1)
call sticks the pk
into the inked_comic
keyword, which is obviously not intended. (and actually results in a int
does not have a dict
exception)
My brain is fried at this point, am I missing something obvious, or is there a better way to do this?
What about a static method on the class to handle this?
colored = ColoredComic.create_from_Inked(pk=ink_id)
colored.colored = True
colored.save()
Untested, but something to this effect (using your code from above)
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
For that simple case, this will work:
inked = InkedComic.object.get(pk=ink_id)
inked.__class__ = ColoredComic
inked.colored = True
inked.save()
精彩评论