Django: доступ к определенному атрибуту нескольких подклассов с наследованием от одного суперкласса
Моя цель - получить доступ к атрибуту подкласса, не зная заранее, какой из двух подклассов был выбран (классы с множественным выбором)
В идеале в суперклассе есть атрибут, который изменяется в зависимости от того, какой подкласс выбран.
Причина в том, что я создал формы непосредственно из подклассов и использую суперкласс в качестве точки входа для доступа к значениям.
Я знаю, что могу использовать true или false с hasattr(horse), но в идеале я спрашиваю, есть ли немного более точное решение, такое как SubClass может сигнализировать SuperClass, какой SubClass использовался.
например, для продукта 8 в моем списке
subclass = getattr(Product(8), 'subclass', 0)
print(subclass)
>> Horse
или же
place = Product.location
Print(place)
>> Stable
Вся "проблема" проистекает из того факта, что я создаю Продукты через Формы Подкласса, в то время как большая часть более поздней логики идет сверху вниз, начиная с Продукта.
class Product(models.Model):
product_name = models.Charfield(max_length=20)
class Car(Product):
engine = models.Charfield(max_length=20)
location = models.Charfield(default="Garage", max_length=20, editable=False)
product = models.OneToOneField(Product, parent_link=True, on_delete=models.CASCADE)
class Horse(Product):
saddle_model = models.Charfield(max_length=20)
location = models.Charfield(default="Stable", max_length=20, editable=False)
product = models.OneToOneField(Product, parent_link=True, on_delete=models.CASCADE)
1 ответ
Если вы хотите получить доступ к свойствам других моделей из модели Продукта, вы можете реализовать метод свойств в Продукте, который проверяет обратную связь между ним и связанными с ним моделями и затем возвращает соответствующее местоположение ( https://docs.djangoproject.com/en/2.1/topics/db/examples/one_to_one/).
class Product(models.Model):
product_name = models.CharField(max_length=20)
@property
def location(self):
"""Return the location of the related subclass"""
if self.car:
return self.car.location
elif self.horse:
return self.horse.location
else:
return None
@property
def product_subclass(self):
"""Return the location of the related subclass"""
if self.car:
return self.car
elif self.horse:
return self.horse
else:
return None
Это должно позволить вам использовать его так:
car_product = Product.objects.create(product_name="Car Product")
car = Car.objects.create(engine="engine", location="123 Fake Street", product=car_product)
print(car_product.location) # Prints "123 Fake Street"
horse_product = Product.objects.create(product_name="Horse Product")
horse = Horse.objects.create(saddle_model="Buckingham", location="1982 Old Street", product=horse_product)
print(horse_product.location) # Prints "1982 Old Street"
Если вы хотите сделать что-то подобное, чтобы вернуть подкласс:
print(car_product.product_subclass) # Prints <Car object>
print(horse_product.product_subclass) # Prints <Horse object>
Эти методы свойств требуют, чтобы запрос к базе данных сверялся с таблицами Car и Horse, поскольку отношение хранится в этих таблицах как product_id
колонка. Так что, чтобы выяснить, если product.car
действителен, ORM выполняет запрос, аналогичный Car.objects.get(product_id=product.pk)