Subclassed django models with integrated querysets
Hire the world's top talent on demand or became one of them at Toptal: https://topt.al/25cXVn
and get $2,000 discount on your first invoice
--------------------------------------------------
Music by Eric Matyas
https://www.soundimage.org
Track title: Puzzle Meditation
--
Chapters
00:00 Subclassed Django Models With Integrated Querysets
01:46 Answer 1 Score 1
03:09 Accepted Answer Score 4
03:39 Answer 3 Score 1
03:53 Answer 4 Score 2
04:04 Thank you
--
Full question
https://stackoverflow.com/questions/2542...
--
Content licensed under CC BY-SA
https://meta.stackexchange.com/help/lice...
--
Tags
#python #django #djangomodels #djangoqueryset #metaclass
#avk47
ACCEPTED ANSWER
Score 4
Basically what you're trying to do is to return the different child classes, while querying a shared base class. That is: you want the leaf classes. Check this snippet for a solution: http://www.djangosnippets.org/snippets/1034/
Also be sure to check out the docs on Django's Contenttypes framework: http://docs.djangoproject.com/en/dev/ref/contrib/contenttypes/ It can be a bit confusing at first, but Contenttypes will solve additional problems you'll probably face when using non-abstract base classes with Django's ORM.
ANSWER 2
Score 2
You want one of these:
http://code.google.com/p/django-polymorphic-models/
https://github.com/bconstantin/django_polymorphic
There are downsides, namely extra queries.
ANSWER 3
Score 1
Okay, this works: https://gist.github.com/348872
The tricky bit was this.
class A(Top):
pass
def newA(cls, *args, **kwargs):
# [all that code you wrote for A.__new__]
A.__new__ = staticmethod(newA)
Now, there's something about how Python binds __new__ that I maybe don't quite understand, but the gist of it is this: django's ModelBase metaclass creates a new class object, rather than using the one that's passed in to its __new__; call that A_prime. Then it sticks all the attributes you had in the class definition for A on to A_prime, but __new__ doesn't get re-bound correctly.
Then when you evaluate A(1), A is actually A_prime here, python calls <A.__new__>(A_prime, 1), which doesn't match up, and it explodes.
So the solution is to define your __new__ after A_prime has been defined.
Maybe this is a bug in django.db.models.base.ModelBase.add_to_class, maybe it's a bug in Python, I don't know.
Now, when I said "this works" earlier, I meant this works in isolation with the minimal object construction test case in the current SVN version of Django. I don't know if it actually works as a Model or is useful in a QuerySet. If you actually use this in production code, I will make a public lightning talk out of it for pdxpython and have them mock you until you buy us all gluten-free pizza.
ANSWER 4
Score 1
Simply stick @staticmethod before the __new__ method.
@staticmethod
def __new__(cls, *args, **kwargs):
print args, kwargs
return super(License, cls).__new__(cls, *args, **kwargs)