With related lookups, I can easily get access to all the models I have to have a generic foreign key. Obviously, this is not what I want to do. I want to restrict it to just a sub set of the models I have -- specifically all the inherit from the abstract model Registry.
My models look like thus:
class Registry(models.Model):
"""A base registry class."""
number = models.BigAutoField(primary_key=True)
when = models.DateField(default=timezone.now)
title = models.CharField(
max_length=1024, default='', blank=True, null=True)
class Meta:
"""The meta class."""
abstract = True
[…]
class Revision(models.Model):
"""A revision model."""
when = models.DateTimeField(default=timezone.now)
identification = models.BigIntegerField()
content_type = models.ForeignKey(
ContentType, on_delete=models.CASCADE, related_name='+')
object_id = models.PositiveIntegerField()
parent = GenericForeignKey('content_type', 'object_id')
[…]
class Document(Registry):
[…]
class Drawing(Registry):
[…]
So that each Registry derived instances can have many different revisions.
And the relevant admin:
class RevisionAdmin(admin.ModelAdmin):
"""Revision administration definition."""
fieldsets = [
('Revision', {
'fields': [
'when',
'identification',
]
}),
('Registry', {
'classes': ('grp-collapse grp-open',),
'fields': ('content_type', 'object_id', )
}),
]
You can use a
limit_choices_to[Django-doc]. Since you want to limit the choices to the descendants, we will need to write some extra logic to calculate these first:We can for example first calculate all the subclasses with this function:
Now we can define a callable to obtain the primary keys of the
ContentTypes that are subclasses of a class, in this caseRegistry:In the
ForeignKeyto theContentType, we can then use thelimited_choices_tofield:Variable number of ascents
We can generalize the number of ascents, by generalizing for example the
get_descendantsfunction:Next we can simply call it with: