Как использовать наследование на основе классов для переопределения родительского класса? - PullRequest
0 голосов
/ 03 октября 2019

В моем ShowChart есть модель с названием Electronic (Electronic.objects.values..etc), в моем классе наследования (ChartElectrical) ее необходимо изменить на Electrical (Electronic.objects.values..etc), здесь я просто передаюЭто. Я не знаю, как это сделать

 class ShowChart(View):
   def get(self, request):
    my_count = Electrical.objects.values('allocated_time')\
        .annotate(complete=Count('allocated_time', filter=Q(batch_18=True)),
                  not_complete=Count('allocated_time', 
                   filter=Q(batch_18=False)),
                  complete_1=Count('allocated_time', 
                       filter=Q(batch_19=True)),
                  not_complete_1=Count('allocated_time', 
                  filter=Q(batch_19=False)),
                  complete_2=Count('allocated_time', 
                     filter=Q(batch_20=True)),
                  not_complete_2=Count('allocated_time', 
                   filter=Q(batch_20=False)),
                  complete_3=Count('allocated_time', 
                   filter=Q(batch_21=True)),
                  not_complete_3=Count('allocated_time', 
                filter=Q(batch_21=False)))

    c_batch_18 = list()
    n_batch_18 = list()
    c_batch_19 = list()
    n_batch_19 = list()
    c_batch_20 = list()
    n_batch_20 = list()
    c_batch_21 = list()
    n_batch_21 = list()

    for entry in my_count:
        c_batch_18.append(entry['complete'] * entry['allocated_time'])
        n_batch_18.append(entry['not_complete'] * entry['allocated_time'])
        c_batch_19.append(entry['complete_1'] * entry['allocated_time'])
        n_batch_19.append(entry['not_complete_1'] * entry['allocated_time'])
        c_batch_20.append(entry['complete_2'] * entry['allocated_time'])
        n_batch_20.append(entry['not_complete_2'] * entry['allocated_time'])
        c_batch_21.append(entry['complete_3'] * entry['allocated_time'])
        n_batch_21.append(entry['not_complete_3'] * entry['allocated_time'])

    survived_series = [sum(c_batch_18), sum(c_batch_19), sum(c_batch_20), sum(c_batch_21), 0]
    not_survived_series = [sum(n_batch_18), sum(n_batch_19), sum(n_batch_20), sum(n_batch_21), 0]

    return render(request, 'chart.html', {'survived_series': json.dumps(survived_series),
                                          'not_survived_series': json.dumps(not_survived_series)})


   class ChartElectrical(ShowChart):
    pass

1 Ответ

0 голосов
/ 03 октября 2019

Я думаю, вам следует переместить my_count часть представления другим методом, а затем переопределить его в дочернем представлении. Как это:

class ShowChart(View):
   def get_my_count(self):
      my_count = Electrical.objects.values('allocated_time')\
        .annotate(complete=Count('allocated_time', filter=Q(batch_18=True)),
                  not_complete=Count('allocated_time', 
                   filter=Q(batch_18=False)),
                  complete_1=Count('allocated_time', 
                       filter=Q(batch_19=True)),
                  not_complete_1=Count('allocated_time', 
                  filter=Q(batch_19=False)),
                  complete_2=Count('allocated_time', 
                     filter=Q(batch_20=True)),
                  not_complete_2=Count('allocated_time', 
                   filter=Q(batch_20=False)),
                  complete_3=Count('allocated_time', 
                   filter=Q(batch_21=True)),
                  not_complete_3=Count('allocated_time', 
                filter=Q(batch_21=False)))
     return my_count

   def get(self, request):
    c_batch_18 = list()
    n_batch_18 = list()
    c_batch_19 = list()
    n_batch_19 = list()
    c_batch_20 = list()
    n_batch_20 = list()
    c_batch_21 = list()
    n_batch_21 = list()

    for entry in self.get_my_count():
        c_batch_18.append(entry['complete'] * entry['allocated_time'])
        n_batch_18.append(entry['not_complete'] * entry['allocated_time'])
        c_batch_19.append(entry['complete_1'] * entry['allocated_time'])
        n_batch_19.append(entry['not_complete_1'] * entry['allocated_time'])
        c_batch_20.append(entry['complete_2'] * entry['allocated_time'])
        n_batch_20.append(entry['not_complete_2'] * entry['allocated_time'])
        c_batch_21.append(entry['complete_3'] * entry['allocated_time'])
        n_batch_21.append(entry['not_complete_3'] * entry['allocated_time'])

    survived_series = [sum(c_batch_18), sum(c_batch_19), sum(c_batch_20), sum(c_batch_21), 0]
    not_survived_series = [sum(n_batch_18), sum(n_batch_19), sum(n_batch_20), sum(n_batch_21), 0]

    return render(request, 'chart.html', {'survived_series': json.dumps(survived_series),
                                          'not_survived_series': json.dumps(not_survived_series)})

class ChartElectrical(ShowChart):
   def get_my_count(self):
      # overriding get_my_count function
      my_count = Electrical.objects.values(...)
      return my_count

Возможные оптимизации

Также вот несколько идей по оптимизации:

1. Вы можете сделать c_batch_18, n_batch_18 и др. Расчеты через аннотацию. Например:

from django.db.models import ExpressionWrapper, IntegerField

mycount = mycount.annotate(c_batch_18=ExpressionWrapper(
            F('complete') * F('allocated_time'), output_field=IntegerField()))
         .annotate(n_batch_18=ExpressionWrapper(
            F('not_complete') * F('allocated_time'), output_field=IntegerField())) # and so on

2. Вы также можете рассчитать Сумма путем агрегирования:

from django.db.models import Sum

my_count_sums = my_count.aggregate(c_batch_18_sum=Sum('c_batch_18'), n_batch_18=Sum('n_batch_18')) # and so on

survived = list(filter(lambda x: x.key().startswith('c_batch'), my_count_sums))

not_survived = list(filter(lambda x: x.key().startswith('n_batch'), my_count_sums))

Используя эти оптимизации, выбудет делать большинство вычислений через БД, а не полагаться на ресурсы Python.

...