diff --git a/adserver/admin.py b/adserver/admin.py index 599cad92..d6e271f0 100644 --- a/adserver/admin.py +++ b/adserver/admin.py @@ -1056,8 +1056,11 @@ class PublisherPayoutAdmin(SimpleHistoryAdmin): @admin.register(PublisherGroup) class PublisherGroupAdmin(SimpleHistoryAdmin): - list_display = ("name", "slug", "modified", "created") - list_filter = ("publishers",) + list_display = ("name", "slug", "default_enabled", "modified", "created") + list_filter = ( + "default_enabled", + "publishers", + ) model = PublisherGroup prepopulated_fields = {"slug": ("name",)} readonly_fields = ("modified", "created") diff --git a/adserver/migrations/0091_publisher_group_default.py b/adserver/migrations/0091_publisher_group_default.py new file mode 100644 index 00000000..d8ca6c62 --- /dev/null +++ b/adserver/migrations/0091_publisher_group_default.py @@ -0,0 +1,29 @@ +# Generated by Django 4.2.4 on 2024-01-10 22:57 +from django.db import migrations +from django.db import models + + +class Migration(migrations.Migration): + + dependencies = [ + ("adserver", "0090_ads_rotated"), + ] + + operations = [ + migrations.AddField( + model_name="historicalpublishergroup", + name="default_enabled", + field=models.BooleanField( + default=False, + help_text="Whether this publisher group is enabled on new campaigns by default", + ), + ), + migrations.AddField( + model_name="publishergroup", + name="default_enabled", + field=models.BooleanField( + default=False, + help_text="Whether this publisher group is enabled on new campaigns by default", + ), + ), + ] diff --git a/adserver/models.py b/adserver/models.py index 4a155b8a..a83519a4 100644 --- a/adserver/models.py +++ b/adserver/models.py @@ -559,6 +559,13 @@ class PublisherGroup(TimeStampedModel): help_text=_("A group of publishers that can be targeted by advertisers"), ) + default_enabled = models.BooleanField( + default=False, + help_text=_( + "Whether this publisher group is enabled on new campaigns by default" + ), + ) + history = HistoricalRecords() class Meta: @@ -715,6 +722,21 @@ def total_value(self): return aggregation or 0.0 + def publisher_group_display(self): + """Helper function to display publisher groups if the selected set isn't the default.""" + default_pub_groups = [ + pg.name + for pg in PublisherGroup.objects.filter(default_enabled=True).order_by( + "name" + ) + ] + campaign_pub_groups = [pg.name for pg in self.publisher_groups.order_by("name")] + + if default_pub_groups != campaign_pub_groups: + return campaign_pub_groups + + return None + class Flight(TimeStampedModel, IndestructibleModel): diff --git a/adserver/staff/forms.py b/adserver/staff/forms.py index a97eded5..8e92bc41 100644 --- a/adserver/staff/forms.py +++ b/adserver/staff/forms.py @@ -44,7 +44,6 @@ class CreateAdvertiserForm(forms.Form): DEFAULT_CPM = 5 DEFAULT_NUM_IMPRESSIONS = 200000 DEFAULT_REGION_TARGETING = ["us-ca", "eu-au-nz"] - DEFAULT_TARGETED_GROUPS = ("ethicalads-network", "readthedocs") # Advertiser information advertiser_name = forms.CharField(label=_("Advertiser name"), max_length=200) @@ -127,11 +126,11 @@ def create_advertiser(self): name=advertiser_name, slug=slugify(advertiser_name), ) + + # Add the default publisher groups to this campaign # TODO: Allow configuring of targeted publisher groups in form - for group_slug in self.DEFAULT_TARGETED_GROUPS: - pub_group = PublisherGroup.objects.filter(slug=group_slug).first() - if pub_group: - campaign.publisher_groups.add(pub_group) + for pub_group in PublisherGroup.objects.filter(default_enabled=True): + campaign.publisher_groups.add(pub_group) flight_name = f"{advertiser_name} Initial Flight" flight = Flight.objects.create( diff --git a/adserver/templates/adserver/includes/flight-metadata.html b/adserver/templates/adserver/includes/flight-metadata.html index 1a6c1f5f..4058470d 100644 --- a/adserver/templates/adserver/includes/flight-metadata.html +++ b/adserver/templates/adserver/includes/flight-metadata.html @@ -125,6 +125,9 @@ {% if flight.targeting_parameters.mobile_traffic %}
  • {% blocktrans with value=flight.targeting_parameters.mobile_traffic %}Mobile traffic: {{ value }}{% endblocktrans %}
  • {% endif %} + {% if flight.campaign.publisher_group_display %} +
  • {% blocktrans with value=flight.campaign.publisher_group_display|join:", " %}Networks: {{ value }}{% endblocktrans %}
  • + {% endif %} {% endif %} diff --git a/adserver/tests/test_staff_actions.py b/adserver/tests/test_staff_actions.py index 44abc945..9beccf36 100644 --- a/adserver/tests/test_staff_actions.py +++ b/adserver/tests/test_staff_actions.py @@ -46,10 +46,12 @@ def setUp(self): self.pub_group_rtd = get( PublisherGroup, slug="readthedocs", + default_enabled=True, ) self.pub_group_ea = get( PublisherGroup, slug="ethicalads-network", + default_enabled=True, ) self.pub_group_other = get( PublisherGroup, @@ -134,7 +136,7 @@ def test_view(self): self.assertIsNotNone(campaign) # Check that the campaign targets the two pub groups (readthedocs and ethicalads-network) - for slug in CreateAdvertiserForm.DEFAULT_TARGETED_GROUPS: + for slug in ("readthedocs", "ethicalads-network"): self.assertTrue(campaign.publisher_groups.filter(slug=slug).exists()) self.assertFalse( campaign.publisher_groups.filter(pk=self.pub_group_other.pk).exists()