mirror of
https://github.com/cisagov/manage.get.gov.git
synced 2025-05-19 19:09:22 +02:00
Add waffle sample and switch
This commit is contained in:
parent
972678d3d2
commit
8e13a305d5
8 changed files with 167 additions and 16 deletions
|
@ -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)
|
|
||||||
|
|
|
@ -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-----------------------------------------------------------###
|
||||||
|
|
|
@ -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=[
|
|
@ -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 = [
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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")
|
||||||
|
|
19
src/registrar/models/waffle_sample.py
Normal file
19
src/registrar/models/waffle_sample.py
Normal 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"
|
19
src/registrar/models/waffle_switch.py
Normal file
19
src/registrar/models/waffle_switch.py
Normal 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"
|
Loading…
Add table
Add a link
Reference in a new issue