Доступ к данным родительской модели из подмодели с помощью внешнего ключа в 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
Вернуться на верх