RelatedObjectDoesNotExist with TabularInline and proxy models
my app's models include the Service model along with three proxy models:
class Service(models.Model):
SERVICE_TYPE_CHOICES = [
('AR', 'Area'),
('OC', 'Occupancy'),
('CO', 'Consumption'),
]
service_type = models.CharField(max_length=2, choices=SERVICE_TYPE_CHOICES)
building = models.ForeignKey(Building, on_delete=models.CASCADE)
def __init__(self, *args, **kwargs):
super(HouseService, self).__init__(*args, **kwargs)
subclasses = {
'AR' : AreaService,
'OC' : OccupancyService,
'CO' : ConsumptionService,
}
self.__class__ = subclasses[self.service_type]
class AreaServiceManager(models.Manager):
def get_queryset(self):
return super(AreaServiceManager, self).get_queryset().filter(service_type='AR')
def create(self, **kwargs):
kwargs.update({'service_type': 'AR'})
return super(AreaServiceManager, self).create(**kwargs)
class AreaService(Service):
objects = AreaServiceManager()
def save(self, *args, **kwargs):
self.service_type = 'AR'
return super(AreaService, self).save(*args, **kwargs)
class Meta:
proxy = True
# Manager and Model class definitions omitted for the other two proxy models
This works as intended such that I can create objects for each proxy model transparently by registering them for the admin interface, and queries for Service.objects
will return the proper proxy/subclass objects.
But when I try to add a TabularInline
to admin.py
–
class ServiceInlineAdmin(admin.TabularInline):
model = Service
extra = 0
class BuildingAdmin(admin.ModelAdmin):
inlines = [ServiceInlineAdmin,]
– I get the following error message for the line self.__class__ = subclasses[self.service_type]
in models.py
(s. above):
__class__
<class 'services.models.Service'>
args
()
kwargs
{}
self
Error in formatting: RelatedObjectDoesNotExist: Service has no building.
subclasses
{'AR': <class 'services.models.AreaService'>,
'CO': <class 'services.models.ConsumptionService'>,
'OC': <class 'services.models.OccupancyService'>}
I retrieved all objects via the Django shell, and check my database: All Service objects/entries are linked to a building. Commenting out the custom __init__
function solves the issue, and all linked services are displayed for each building (but I obviously lose the ability to properly subclass the Service objects).
Any pointers to the cause of this error are greatly appreciated.
Problem solved. It turned out that the TabularInline
form created 4 additional empty Service instances (regardless of extra = 0
). To circumvent this issue, I modified my custom __init__
function like this:
def __init__(self, *args, **kwargs):
super(Service, self).__init__(*args, **kwargs)
subclasses = {
'AR' : AreaService,
'OC' : OccupancyService,
'CO' : ConsumptionService,
}
if self.id:
self.__class__ = subclasses[self.service_type]