RelatedObjectDoesNotExist с TabularInline и прокси-моделями
модели моего приложения включают модель Service, а также три прокси-модели:
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
Это работает так, как и предполагалось, я могу создавать объекты для каждой прокси-модели прозрачно, регистрируя их в интерфейсе администратора, и запросы Service.objects
будут возвращать соответствующие объекты прокси/подкласса.
Но когда я пытаюсь добавить TabularInline
к admin.py
-
class ServiceInlineAdmin(admin.TabularInline):
model = Service
extra = 0
class BuildingAdmin(admin.ModelAdmin):
inlines = [ServiceInlineAdmin,]
- Я получаю следующее сообщение об ошибке для строки self.__class__ = subclasses[self.service_type]
в models.py
(с. выше):
__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'>}
Я извлек все объекты через оболочку Django и проверил свою базу данных: Все объекты/записи услуг связаны со зданием. Комментирование пользовательской функции __init__
решает проблему, и все связанные услуги отображаются для каждого здания (но я, очевидно, теряю возможность правильно подклассифицировать объекты Service).
Любые указания на причину этой ошибки будут высоко оценены.
Проблема решена. Оказалось, что форма TabularInline
создавала 4 дополнительных пустых экземпляра Service (независимо от extra = 0
). Чтобы обойти эту проблему, я модифицировал свою пользовательскую функцию __init__
следующим образом:
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]