This is the approach I've taken to access instances of child models from their parent. Functionally it's very similar to snippets 1031 and 1034, but without the use of django.contrib.contenttypes.
Usage:
class Post(ParentModel):
title = models.CharField(max_length=50)
objects = models.Manager()
children = ChildManager()
def __unicode__(self):
return self.title
def get_parent_model(self):
return Post
class Article(Post):
text = models.TextField()
class Photo(Post):
image = models.ImageField(upload_to='photos/')
class Link(Post):
url = models.URLField()
In this case, the Post.children manager will return a queryset containing instances of the appropriate child model, rather than instances of Post.
>>> Post.objects.all()
[<Post: Django>, <Post: Make a Tumblelog>, <Post: Self Portrait>]
>>> Post.children.all()
[<Link: Django>, <Article: Make a Tumblelog>, <Photo: Self Portrait>]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | from django.db import models
from django.db.models.query import QuerySet
class ChildQuerySet(QuerySet):
def iterator(self):
for obj in super(ChildQuerySet, self).iterator():
yield obj.get_child_object()
class ChildManager(models.Manager):
def get_query_set(self):
return ChildQuerySet(self.model)
class ParentModel(models.Model):
_child_name = models.CharField(max_length=100, editable=False)
class Meta:
abstract = True
def save(self, *args, **kwargs):
self._child_name = self.get_child_name()
super(ParentModel, self).save(*args, **kwargs)
def get_child_name(self):
if type(self) is self.get_parent_model():
return self._child_name
return self.get_parent_link().related_query_name()
def get_child_object(self):
return getattr(self, self.get_child_name())
def get_parent_link(self):
return self._meta.parents[self.get_parent_model()]
def get_parent_model(self):
raise NotImplementedError
def get_parent_object(self):
return getattr(self, self.get_parent_link().name)
|
More like this
- Add Toggle Switch Widget to Django Forms by OgliariNatan 1 month, 4 weeks ago
- get_object_or_none by azwdevops 5 months, 3 weeks ago
- Mask sensitive data from logger by agusmakmun 7 months, 2 weeks ago
- Template tag - list punctuation for a list of items by shapiromatron 1 year, 9 months ago
- JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 1 year, 9 months ago
Comments
Nice.
1031 and 1034 solved the problem, but this was the usage I was looking to get from the solution. Thanks!
#
Thanks, excellent snippet!
#
Slick.
#
That's exactly what I was looking for, thanks!
#
Please login first before commenting.