Как выполнить вычисления между childreen абстрактного класса в Django - PullRequest
0 голосов
/ 02 апреля 2020

Я использую абстрактный базовый класс для выполнения простых вычислений в моих моделях, как показано ниже:

class Base(models.Model):

    name = models.CharField(max_length=100, null=True)
    width = models.DecimalField(max_digits=10, decimal_places=2, default=1, validators=[MinValueValidator(1)])
    length = models.DecimalField(max_digits=10, decimal_places=2, default=1, validators=[MinValueValidator(1)])

    class Meta:
        abstract = True

class Room(Base):

    room_area = models.DecimalField(max_digits=10, decimal_places=2, default=1, validators=[MinValueValidator(1)])

    def save(self, *args, **kwargs):
        self.room_area = self.length*self.width
        super().save(*args, **kwargs)

    def __str__(self):
        return self.name

class Hall(Base):

    hall_area = models.DecimalField(max_digits=10, decimal_places=2, default=1, validators=[MinValueValidator(1)])
    room = models.ForeignKey(Room, on_delete=models.SET_NULL, null=True)

    def save(self, *args, **kwargs):
        self.hall_area = self.length*self.width
        super().save(*args, **kwargs)

    def __str__(self):
        return self.name

Допустим, мне нужно найти building_area, что равно building_area = room_area + hall_area. Моя проблема в том, что building_area будет использоваться другими моделями и потомками Base (для вычисления других переменных). Я думал, что было бы лучше, если бы я сделал расчет building_area в Base. Я новичок в Python и Django, поэтому не совсем уверен, как это реализовать. Может кто-нибудь предложить решение или указать на хороший пример?

1 Ответ

1 голос
/ 02 апреля 2020

Я рекомендую делегировать этот вид операций с помощью функции на подклассах:

У меня есть следующий пример:

from django.db import models

from ecommerce.shipping.models import Shipping


class Sea(Shipping):
    weight = models.PositiveIntegerField(null=True, default=0)

    @property
    def value(self):
        return self.cost * self.weight


class Ground(Shipping):
    weight = models.PositiveIntegerField(null=True, default=0)

    @property
    def value(self):
        return self.cost * self.weight


class Air(Shipping):
    weight = models.PositiveIntegerField(null=True, default=0)

    @property
    def value(self):
        return self.cost * self.weight

Вы можете адаптироваться к собственному коду, но имея Этот вид подклассов вы можете легко обработать, чтобы ваши вычисления

self.sea = Sea(weight=10, cost=2)

, если мы назовем sea.value, результат будет 20 Из-за return self.cost * self.weight

...