How do I access the child classes of an object in django without knowing the name of the child class?
(Update: For Django 1.2 and newer, which can follow select_related queries across reverse OneToOneField relations (and thus down inheritance hierarchies), there's a better technique available which doesn't require the added real_type
field on the parent model. It's available as InheritanceManager in the django-model-utils project.)
The usual way to do this is to add a ForeignKey to ContentType on the Parent model which stores the content type of the proper "leaf" class. Without this, you may have to do quite a number of queries on child tables to find the instance, depending how large your inheritance tree is. Here's how I did it in one project:
from django.contrib.contenttypes.models import ContentType
from django.db import models
class InheritanceCastModel(models.Model):
"""
An abstract base class that provides a ``real_type`` FK to ContentType.
For use in trees of inherited models, to be able to downcast
parent instances to their child types.
"""
real_type = models.ForeignKey(ContentType, editable=False)
def save(self, *args, **kwargs):
if self._state.adding:
self.real_type = self._get_real_type()
super(InheritanceCastModel, self).save(*args, **kwargs)
def _get_real_type(self):
return ContentType.objects.get_for_model(type(self))
def cast(self):
return self.real_type.get_object_for_this_type(pk=self.pk)
class Meta:
abstract = True
This is implemented as an abstract base class to make it reusable; you could also put these methods and the FK directly onto the parent class in your particular inheritance hierarchy.
This solution won't work if you aren't able to modify the parent model. In that case you're pretty much stuck checking all the subclasses manually.
How do I know which child class a Django model object is when selected through the parent class?
This is a common issue and still seems to be one of Django's uglier ducklings.
You could at least rearrange for 2 cents of DRY gain:
from django.core.exceptions import ObjectDoesNotExist
@property
def event_type(self):
for et in ('ticketedevent', 'rsvpevent', 'sillyhatsonlyevent', ...):
try:
getattr(self, et)
return et
except ObjectDoesNotExist:
pass
@property
def admin_link(self):
return reverse('admin:events_%s_change' % self.event_type, args=(self.id,))
If you really want to be fancy, you could use Event.__subclasses__
and generate the list of event types.
What's the easiest way of finding a child instance from a parent instance in Django?
Various forms of this question pop up here regularly. This answer demonstrates a generic way to "cast" a parent type to its proper subtype without having to query every subtype table. That way you wouldn't need to define a monster get_absolute_url on the parent which covers all the cases, you'd just convert to the child type and call get_absolute_url normally.
Find django object by .id only (unknown Model)
It is no a dumb question at all.
You may want to take a look at model inheritance:
https://docs.djangoproject.com/en/2.2/topics/db/models/#model-inheritance
You can setup an abstract equipment base model in which you put your id field. Then each of your specific equipment model (camera, display, switcher, etc.) inherit form this base table.
You can bonify your base model with this technic in order to get the child object from a search on its parent.
django - how do i access the child's Meta from the parent?
Try using self._meta
for accessing Meta
class for self
.
Django: Query self referencing objects with no child elements
You can use isnull
with the related_query_name
:
class Category(models.Model):
# ...
parent = models.ForeignKey('self', null=True, related_name='children', related_query_name='child')
Category.objects.filter(child__isnull=True)
Here, I would recommend to specify at least a meaningful related_name
!
If you specify only a related_name
, the related_query_name
defaults to that name (here: children
). If you specify none of the two, the rqn defaults to the model name: category
, not category_set
Category.objects.filter(category__isnull=True) # not so informative
Related Topics
Unicodedecodeerror: 'Ascii' Codec Can't Decode Byte 0Xef in Position 1
Why Is Parenthesis in Print Voluntary in Python 2.7
How to Put Individual Tags for a Matplotlib Scatter Plot
Plotting a 2D Heatmap with Matplotlib
Subprocess.Call Using String VS Using List
Python: Defining My Own Operators
How to Add an Image in Tkinter
How to Plot Multiple Seaborn Jointplot in Subplot
Zip Variable Empty After First Use
How to Check If Two Segments Intersect
How to Make a Tkinter Window Jump to the Front
How Could I Use Requests in Asyncio
Returning the Product of a List
How to Make Program Go Back to the Top of the Code Instead of Closing