Доступ к данным родительской модели из подмодели с помощью внешнего ключа в Django
Я совсем новичок в API и Django, прошу простить меня, если это глупый вопрос, но я не могу разобраться в этом
У меня есть 2 модели (ProductOrder и Product). Модель ProductOrder имеет внешний ключ от Product.
Вот 2 модели.
class Product(models.Model):
name = models.CharField(max_length = 100)
price = models.IntegerField(default = 1)
def __str__(self) -> str:
return f'{self.name} Price => {self.price}'
class ProductOrder(models.Model):
product_id = models.ForeignKey(Product, on_delete=models.CASCADE)
order_dis = models.FloatField()
price = ** Need to get the price of the product using the product id **
order_date = models.DateField()
dis_price = price - order_dis
def __str__(self) -> str:
return f'{self.order_date} {self.dis_price}'
Я собираюсь создать API и хочу ввести только id товара и получить доступ к цене товара, что поможет рассчитать некоторые другие поля. Возможно ли это?
Обычно это делается с помощью вычислений при запросе данных.
Вы должны задать себе вопрос: "Хранить ли мне эти данные в базе данных, или вычислить их на основе данных в базе?". В данном случае, вероятно, правильным будет второе.
Это можно сделать с помощью QuerySet Annotate.
Для примера создадим несколько объектов:
product = Product.objects.create(name="bagel", price=1)
ProductOrder.objects.create(product=product, order_dis=2.5)
Теперь сделаем запрос для этого заказа
order = ProductOrder.objects.annotate(
price=F("product__price"),
dis_price=F("product__price") - F("order_dis"),
).first()
print(order.price) # 1
print(order.dis_price) # 1.5
Вы также можете реализовать его в Python, чтобы получить значение для одного объекта:
class ProductOrder(models.Model):
product = models.ForeignKey(Product, on_delete=models.CASCADE)
order_dis = models.FloatField()
order_date = models.DateField(auto_now=True)
def get_dis_price(self) -> float:
return self.product.price - self.order_dis
def __str__(self) -> str:
return f'{self.order_date} {self.dis_price}'
Тогда вы также сможете сделать
order.get_dis_price() # 1.5