Add waffle sample and switch

This commit is contained in:
zandercymatics 2024-05-01 09:18:05 -06:00
parent 972678d3d2
commit 8e13a305d5
No known key found for this signature in database
GPG key ID: FF4636ABEC9682B7
8 changed files with 167 additions and 16 deletions

View file

@ -15,9 +15,8 @@ from django.contrib.contenttypes.models import ContentType
from django.urls import reverse from django.urls import reverse
from dateutil.relativedelta import relativedelta # type: ignore from dateutil.relativedelta import relativedelta # type: ignore
from epplibwrapper.errors import ErrorCode, RegistryError from epplibwrapper.errors import ErrorCode, RegistryError
from waffle.admin import FlagAdmin from waffle.admin import FlagAdmin, SampleAdmin, SwitchAdmin
from registrar.models import Contact, Domain, DomainRequest, DraftDomain, User, Website from registrar.models import Contact, Domain, DomainRequest, DraftDomain, User, Website
from waffle.models import Sample, Switch
from registrar.utility.errors import FSMDomainRequestError, FSMErrorCodes from registrar.utility.errors import FSMDomainRequestError, FSMErrorCodes
from registrar.views.utility.mixins import OrderableFieldsMixin from registrar.views.utility.mixins import OrderableFieldsMixin
from django.contrib.admin.views.main import ORDER_VAR from django.contrib.admin.views.main import ORDER_VAR
@ -2168,6 +2167,22 @@ class WaffleFlagAdmin(FlagAdmin):
fields = "__all__" fields = "__all__"
class WaffleSwitchAdmin(SwitchAdmin):
class Meta:
"""Contains meta information about this class"""
model = models.WaffleSwitch
fields = "__all__"
class WaffleSampleAdmin(SampleAdmin):
class Meta:
"""Contains meta information about this class"""
model = models.WaffleSample
fields = "__all__"
admin.site.unregister(LogEntry) # Unregister the default registration admin.site.unregister(LogEntry) # Unregister the default registration
admin.site.register(LogEntry, CustomLogEntryAdmin) admin.site.register(LogEntry, CustomLogEntryAdmin)
@ -2192,12 +2207,7 @@ admin.site.register(models.DomainRequest, DomainRequestAdmin)
admin.site.register(models.TransitionDomain, TransitionDomainAdmin) admin.site.register(models.TransitionDomain, TransitionDomainAdmin)
admin.site.register(models.VerifiedByStaff, VerifiedByStaffAdmin) admin.site.register(models.VerifiedByStaff, VerifiedByStaffAdmin)
# Register our custom waffle flag implementation # Register our custom waffle implementations
admin.site.register(models.WaffleFlag, WaffleFlagAdmin) admin.site.register(models.WaffleFlag, WaffleFlagAdmin)
admin.site.register(models.WaffleSample, WaffleSampleAdmin)
# Unregister samples and switches from django-waffle, as we currently don't use these. admin.site.register(models.WaffleSwitch, WaffleSwitchAdmin)
# Django admin sorts different "sites" alphabetically, and offers little customization for them.
# If we do need to use these, we should also consider using this library:
# https://pypi.org/project/django-reorder-admin/
admin.site.unregister(Sample)
admin.site.unregister(Switch)

View file

@ -328,8 +328,17 @@ SERVER_EMAIL = "root@get.gov"
WAFFLE_CREATE_MISSING_FLAGS = False WAFFLE_CREATE_MISSING_FLAGS = False
# The model that will be used to keep track of flags. Extends AbstractUserFlag. # The model that will be used to keep track of flags. Extends AbstractUserFlag.
# Used to replace the default flag class (for customization purposes).
WAFFLE_FLAG_MODEL = "registrar.WaffleFlag" WAFFLE_FLAG_MODEL = "registrar.WaffleFlag"
# The model that will be used to keep track of switches. Extends AbstractBaseSwitch.
# Used to replace the default switch class (for customization purposes).
WAFFLE_SWITCH_MODEL = "registrar.WaffleSwitch"
# The model that will be used to keep track of samples. Extends AbstractBaseSample.
# Used to replace the default sample class (for customization purposes).
WAFFLE_SAMPLE_MODEL = "registrar.WaffleSample"
# endregion # endregion
# region: Headers-----------------------------------------------------------### # region: Headers-----------------------------------------------------------###

View file

@ -1,4 +1,4 @@
# Generated by Django 4.2.10 on 2024-04-30 16:56 # Generated by Django 4.2.10 on 2024-05-01 15:10
from django.conf import settings from django.conf import settings
from django.db import migrations, models from django.db import migrations, models
@ -13,6 +13,93 @@ class Migration(migrations.Migration):
] ]
operations = [ operations = [
migrations.CreateModel(
name="WaffleSample",
fields=[
("id", models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")),
(
"name",
models.CharField(
help_text="The human/computer readable name.", max_length=100, unique=True, verbose_name="Name"
),
),
(
"percent",
models.DecimalField(
decimal_places=1,
help_text="A number between 0.0 and 100.0 to indicate a percentage of the time this sample will be active.",
max_digits=4,
verbose_name="Percent",
),
),
(
"note",
models.TextField(blank=True, help_text="Note where this Sample is used.", verbose_name="Note"),
),
(
"created",
models.DateTimeField(
db_index=True,
default=django.utils.timezone.now,
help_text="Date when this Sample was created.",
verbose_name="Created",
),
),
(
"modified",
models.DateTimeField(
default=django.utils.timezone.now,
help_text="Date when this Sample was last modified.",
verbose_name="Modified",
),
),
],
options={
"verbose_name": "waffle sample",
"verbose_name_plural": "Waffle samples",
},
),
migrations.CreateModel(
name="WaffleSwitch",
fields=[
("id", models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")),
(
"name",
models.CharField(
help_text="The human/computer readable name.", max_length=100, unique=True, verbose_name="Name"
),
),
(
"active",
models.BooleanField(default=False, help_text="Is this switch active?", verbose_name="Active"),
),
(
"note",
models.TextField(blank=True, help_text="Note where this Switch is used.", verbose_name="Note"),
),
(
"created",
models.DateTimeField(
db_index=True,
default=django.utils.timezone.now,
help_text="Date when this Switch was created.",
verbose_name="Created",
),
),
(
"modified",
models.DateTimeField(
default=django.utils.timezone.now,
help_text="Date when this Switch was last modified.",
verbose_name="Modified",
),
),
],
options={
"verbose_name": "waffle switch",
"verbose_name_plural": "Waffle switches",
},
),
migrations.CreateModel( migrations.CreateModel(
name="WaffleFlag", name="WaffleFlag",
fields=[ fields=[

View file

@ -25,6 +25,7 @@ def delete_flags(apps, schema_editor):
Deletes all prexisting flags. Deletes all prexisting flags.
Does not delete flags not defined in this scope (user generated). Does not delete flags not defined in this scope (user generated).
""" """
# This is a bit of a hack to get around "apps" not knowing what the concept of a constant is # This is a bit of a hack to get around "apps" not knowing what the concept of a constant is
default_flags = WaffleFlag.get_default_waffle_flags() default_flags = WaffleFlag.get_default_waffle_flags()
WaffleFlag.delete_waffle_flags_for_migrations(apps, default_flags) WaffleFlag.delete_waffle_flags_for_migrations(apps, default_flags)
@ -32,7 +33,7 @@ def delete_flags(apps, schema_editor):
class Migration(migrations.Migration): class Migration(migrations.Migration):
dependencies = [ dependencies = [
("registrar", "0090_waffleflag"), ("registrar", "0090_wafflesample_waffleswitch_waffleflag"),
] ]
operations = [ operations = [

View file

@ -16,6 +16,8 @@ from .website import Website
from .transition_domain import TransitionDomain from .transition_domain import TransitionDomain
from .verified_by_staff import VerifiedByStaff from .verified_by_staff import VerifiedByStaff
from .waffle_flag import WaffleFlag from .waffle_flag import WaffleFlag
from .waffle_sample import WaffleSample
from .waffle_switch import WaffleSwitch
__all__ = [ __all__ = [
"Contact", "Contact",
@ -35,6 +37,8 @@ __all__ = [
"TransitionDomain", "TransitionDomain",
"VerifiedByStaff", "VerifiedByStaff",
"WaffleFlag", "WaffleFlag",
"WaffleSwitch",
"WaffleSample",
] ]
auditlog.register(Contact) auditlog.register(Contact)
@ -54,3 +58,5 @@ auditlog.register(Website)
auditlog.register(TransitionDomain) auditlog.register(TransitionDomain)
auditlog.register(VerifiedByStaff) auditlog.register(VerifiedByStaff)
auditlog.register(WaffleFlag) auditlog.register(WaffleFlag)
auditlog.register(WaffleSample)
auditlog.register(WaffleSwitch)

View file

@ -22,10 +22,10 @@ class WaffleFlag(AbstractUserFlag):
def get_default_waffle_flags(): def get_default_waffle_flags():
""" """
Defines which waffle flags should be created at startup. Defines which waffle flags should be created at startup.
Add to this list if you want to add another flag that is generated at startup.
Add to this function if you want to add another flag that is generated at startup.
When you do so, you will need to add a new instance of `0091_create_waffle_flags_v{version_number}` When you do so, you will need to add a new instance of `0091_create_waffle_flags_v{version_number}`
in registrar/migrations for that change to update automatically on migrate. in registrar/migrations for that change to update automatically on migrate.
This has to exist here, as from the context of migrations, it cannot access constants
""" """
default_flags = [ default_flags = [
# flag_name, flag_note # flag_name, flag_note
@ -37,7 +37,7 @@ class WaffleFlag(AbstractUserFlag):
@staticmethod @staticmethod
def create_waffle_flags_for_migrations(apps, default_waffle_flags): def create_waffle_flags_for_migrations(apps, default_waffle_flags):
""" """
Creates a pre-defined list of flags for our migrations. Creates a list of flags for our migrations.
""" """
logger.info("Creating default waffle flags...") logger.info("Creating default waffle flags...")
WaffleFlag = apps.get_model("registrar", "WaffleFlag") WaffleFlag = apps.get_model("registrar", "WaffleFlag")
@ -57,7 +57,7 @@ class WaffleFlag(AbstractUserFlag):
@staticmethod @staticmethod
def delete_waffle_flags_for_migrations(apps, default_waffle_flags): def delete_waffle_flags_for_migrations(apps, default_waffle_flags):
""" """
Delete a pre-defined list of flags for our migrations (the reverse_code operation). Delete a list of flags for our migrations (the reverse_code operation).
""" """
logger.info("Deleting default waffle flags...") logger.info("Deleting default waffle flags...")
WaffleFlag = apps.get_model("registrar", "WaffleFlag") WaffleFlag = apps.get_model("registrar", "WaffleFlag")

View file

@ -0,0 +1,19 @@
from waffle.models import AbstractBaseSample
import logging
logger = logging.getLogger(__name__)
class WaffleSample(AbstractBaseSample):
"""
Custom implementation of django-waffles 'sample' object.
Read more here: https://waffle.readthedocs.io/en/stable/types/sample.html
Use this class when dealing with samples.
"""
class Meta:
"""Contains meta information about this class"""
verbose_name = "waffle sample"
verbose_name_plural = "Waffle samples"

View file

@ -0,0 +1,19 @@
from waffle.models import AbstractBaseSwitch
import logging
logger = logging.getLogger(__name__)
class WaffleSwitch(AbstractBaseSwitch):
"""
Custom implementation of django-waffles 'switch' object.
Read more here: https://waffle.readthedocs.io/en/stable/types/switch.html
Use this class when dealing with switches.
"""
class Meta:
"""Contains meta information about this class"""
verbose_name = "waffle switch"
verbose_name_plural = "Waffle switches"