Django - улучшить запрос, состоящий из полей многие-ко-многим и foreignKey - PullRequest
0 голосов
/ 16 апреля 2020

Я хочу экспортировать отчет из доступных данных в файл CSV. Я написал следующий код, и он отлично работает. Что вы предлагаете для улучшения запроса?

Модели:

class shareholder(models.Model):
   title = models.CharField(max_length=100)
   code = models.IntegerField(null=False)

class Company(models.Model):
   isin = models.CharField(max_length=20, null=False)
   cisin = models.CharField(max_length=20)
   name_fa = models.CharField(max_length=100)
   name_en = models.CharField(max_length=100)

class company_shareholder(models.Model):
   company = models.ManyToManyField(Company)
   shareholder = models.ForeignKey(shareholder, on_delete=models.SET_NULL, null=True)
   share = models.IntegerField(null = True) # TODO: *1000000 
   percentage = models.DecimalField(max_digits=8, decimal_places=2, null=True)
   difference = models.DecimalField(max_digits=11, decimal_places=2, null=True)
   update_datetime = models.DateTimeField(null=True)

Просмотр:

def ExportAllShare(request):
   response = HttpResponse(content_type='text/csv')
   response['Content-Disposition'] = 'attachment; filename="shares.csv"'
   response.write(u'\ufeff'.encode('utf8'))
   writer = csv.writer(response)
   writer.writerow(['date','company','shareholder title','shareholder code','difference','share'])
   results = company_shareholder.objects.all()
   for result in results:
      row = (
        result.update_datetime,
        result.company.first().name_fa,
        result.shareholder.title,
        result.shareholder.code,
        result.difference,
        result.share,
           )
      writer.writerow(row)
   return (response)

1 Ответ

0 голосов
/ 16 апреля 2020

Прежде всего, если он работает нормально для вас, тогда он работает нормально, не оптимизируйте преждевременно.

Но в таком запросе вы сталкиваетесь с n+1 problem. В Django вы избегаете этого, используя select_related и prefetch_related. Например:

results = company_shareholder.objects.select_related('shareholder').prefetch_related('company').all()

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

Кроме того, я настоятельно рекомендую вам следовать руководству по стилю PEP8 и назвать свои классы в Соглашение CapWords, такое как Shareholder и CompanyShareholder.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...