|
17 | 17 | from django.contrib.auth.models import UserManager |
18 | 18 | from django.core import exceptions |
19 | 19 | from django.core.exceptions import ValidationError |
| 20 | +from django.core.paginator import Paginator |
20 | 21 | from django.core.validators import MaxValueValidator |
21 | 22 | from django.core.validators import MinValueValidator |
22 | 23 | from django.db import models |
@@ -53,6 +54,20 @@ def get_or_none(self, *args, **kwargs): |
53 | 54 | with suppress(self.model.DoesNotExist, ValidationError): |
54 | 55 | return self.get(*args, **kwargs) |
55 | 56 |
|
| 57 | + def paginated(self, per_page=5000): |
| 58 | + """ |
| 59 | + Iterate over a (large) QuerySet by chunks of ``per_page`` items. |
| 60 | + This technique is essential for preventing memory issues when iterating |
| 61 | + See these links for inspiration: |
| 62 | + https://nextlinklabs.com/resources/insights/django-big-data-iteration |
| 63 | + https://stackoverflow.com/questions/4222176/why-is-iterating-through-a-large-django-queryset-consuming-massive-amounts-of-me/ |
| 64 | + """ |
| 65 | + paginator = Paginator(self, per_page=per_page) |
| 66 | + for page_number in paginator.page_range: |
| 67 | + page = paginator.page(page_number) |
| 68 | + for object in page.object_list: |
| 69 | + yield object |
| 70 | + |
56 | 71 |
|
57 | 72 | class VulnerabilityQuerySet(BaseQuerySet): |
58 | 73 | def with_cpes(self): |
@@ -770,6 +785,10 @@ def url(self): |
770 | 785 | return f"https://github.com/nodejs/security-wg/blob/main/vuln/npm/{id}.json" |
771 | 786 |
|
772 | 787 |
|
| 788 | +class AdvisoryQuerySet(BaseQuerySet): |
| 789 | + pass |
| 790 | + |
| 791 | + |
773 | 792 | class Advisory(models.Model): |
774 | 793 | """ |
775 | 794 | An advisory represents data directly obtained from upstream transformed |
@@ -809,6 +828,7 @@ class Advisory(models.Model): |
809 | 828 | "module name importing the advisory. Eg:" |
810 | 829 | "vulnerabilities.importers.nginx.NginxImporter", |
811 | 830 | ) |
| 831 | + objects = AdvisoryQuerySet.as_manager() |
812 | 832 |
|
813 | 833 | class Meta: |
814 | 834 | unique_together = ["aliases", "unique_content_id", "date_published"] |
|
0 commit comments