From bb324e4f5427ed2a132685741775062af43855e8 Mon Sep 17 00:00:00 2001 From: Pooja Thamb Date: Fri, 9 Oct 2026 08:44:06 +0530 Subject: [PATCH] Add Curator model and link curation advisories to curators Reference: #2442 Signed-off-by: Pooja Thamb --- .../0144_curator_advisoryv2_curator.py | 51 +++++++++++++++++++ vulnerabilities/models.py | 27 ++++++++++ vulnerabilities/tests/test_curator.py | 15 ++++++ 3 files changed, 93 insertions(+) create mode 100644 vulnerabilities/migrations/0144_curator_advisoryv2_curator.py create mode 100644 vulnerabilities/tests/test_curator.py diff --git a/vulnerabilities/migrations/0144_curator_advisoryv2_curator.py b/vulnerabilities/migrations/0144_curator_advisoryv2_curator.py new file mode 100644 index 000000000..bf69a8ddd --- /dev/null +++ b/vulnerabilities/migrations/0144_curator_advisoryv2_curator.py @@ -0,0 +1,51 @@ +# Generated by Django 5.2.11 on 2026-10-08 03:37 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ( + "vulnerabilities", + "0143_remove_impactedpackageaffecting_vulnerabili_impacte_1904b9_idx_and_more", + ), + ] + + operations = [ + migrations.CreateModel( + name="Curator", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, primary_key=True, serialize=False, verbose_name="ID" + ), + ), + ( + "name", + models.CharField(help_text="Name of the curator.", max_length=100, unique=True), + ), + ( + "created_at", + models.DateTimeField( + auto_now_add=True, + help_text="Timestamp indicating when this curator was added.", + ), + ), + ], + ), + migrations.AddField( + model_name="advisoryv2", + name="curator", + field=models.ForeignKey( + blank=True, + help_text="The curator who submitted this curation advisory.", + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="curations", + to="vulnerabilities.curator", + ), + ), + ] diff --git a/vulnerabilities/models.py b/vulnerabilities/models.py index 6b115b1e2..20c433158 100644 --- a/vulnerabilities/models.py +++ b/vulnerabilities/models.py @@ -2923,6 +2923,24 @@ def to_dict(self): } +class Curator(models.Model): + """A person who submits curations for advisories.""" + + name = models.CharField( + max_length=100, + unique=True, + help_text="Name of the curator.", + ) + + created_at = models.DateTimeField( + auto_now_add=True, + help_text="Timestamp indicating when this curator was added.", + ) + + def __str__(self): + return self.name + + class AdvisoryV2QuerySet(BaseQuerySet): def latest_for_avid(self, avid: str): try: @@ -3229,6 +3247,15 @@ class AdvisoryV2(models.Model): help_text="Indicates whether this is a curation advisory.", ) + curator = models.ForeignKey( + Curator, + null=True, + blank=True, + on_delete=models.SET_NULL, + related_name="curations", + help_text="The curator who submitted this curation advisory.", + ) + date_published = models.DateTimeField( blank=True, null=True, diff --git a/vulnerabilities/tests/test_curator.py b/vulnerabilities/tests/test_curator.py new file mode 100644 index 000000000..a6d7ef93e --- /dev/null +++ b/vulnerabilities/tests/test_curator.py @@ -0,0 +1,15 @@ +import pytest + +from vulnerabilities.models import Curator + + +@pytest.mark.django_db +def test_curator_str_returns_name(): + curator = Curator.objects.create(name="John") + assert str(curator) == "John" + + +@pytest.mark.django_db +def test_curator_has_no_curations_by_default(): + curator = Curator.objects.create(name="John") + assert curator.curations.count() == 0