tag:blogger.com,1999:blog-7176062489626496619.post7971217431896570400..comments2023-05-03T11:51:28.484-04:00Comments on Lazy Pythonista: A Second Look at Inheritance and Polymorphism with DjangoAlexhttp://www.blogger.com/profile/14054821112394577330noreply@blogger.comBlogger3125tag:blogger.com,1999:blog-7176062489626496619.post-65568387378059562342009-02-11T12:39:00.000-05:002009-02-11T12:39:00.000-05:00I do this using an FK to ContentType as well. The...I do this using an FK to ContentType as well. The metaclass idea is interesting; I just have a cast() method on the InheritanceMixin that I call manually if I want to cast to the subclass type (because I don't always need to). Seems like with a little work it would be possible to write a manager that gets all the objects as their subclass type with only k+1 queries (one for the superclass table, one for each relevant subclass table) rather than n+1.Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-7176062489626496619.post-73438227773466256542009-02-11T00:20:00.000-05:002009-02-11T00:20:00.000-05:00Mike,You raise a couple of really good points, esp...Mike,<BR/><BR/>You raise a couple of really good points, especially with regards to using a ContentType foreignkey. The one disadvantage of that approach is that you'll lose the advantages from #7270, since you'll be doing a whole new query and bypassing the objects cache, on the other hand that way clearly benefits from simple PK based caching(as I've also written about).<BR/><BR/>And yes, one of the unfortunate effects of using the MetaClass is that it's all or nothing behavior.Alexhttps://www.blogger.com/profile/14054821112394577330noreply@blogger.comtag:blogger.com,1999:blog-7176062489626496619.post-27492579484682150122009-02-11T00:16:00.000-05:002009-02-11T00:16:00.000-05:00Nice post. We're doing something similar on a proj...Nice post. We're doing something similar on a project I'm working on. A few thoughts:<BR/><BR/>Why not user a ForeignKey to ContentType instead of storing the class name in a char field? That should resolve all of your problems w/ traversing the mro and whatnot. <BR/><BR/>In save() you'd do:<BR/>self.content_type = ContentType.objects.get_for_model(self)<BR/><BR/>And in get_object() you'd do:<BR/>leaf_type = self.content_type<BR/>if not leaf_type:<BR/> return self<BR/>leaf_class = leaf_type.model_class()<BR/> if isinstance(self, leaf_class):<BR/> return self<BR/>return leaf_class.objects.get(pk=self.pk)<BR/><BR/>The metaclass you're using is interesting. I have mixed feelings about it. What we're doing is replacing the default manager with our own subclassed manager (we dynamically subclass the existing Manager), then that manager returns a custom QuerySet that dynamically subclasses the existing Manager's QuerySet. Converting to the 'leaf' objects is handled by our QuerySet subclass in get(), latest(), and __iter__(). <BR/><BR/>Your metaclass is actually cleaner than the one we're using, which I like. But with ours you have the ability to create a second manager that won't do the additional work to get the subclass, which is a nice feature.Anonymousnoreply@blogger.com