✨(activation-codes) allow code customization
The activation codes can be fully customized on creation and not edited afterward.
This commit is contained in:
@@ -33,7 +33,6 @@ class ActivationCodeAdmin(admin.ModelAdmin):
|
||||
|
||||
readonly_fields = (
|
||||
"id",
|
||||
"code",
|
||||
"current_uses",
|
||||
"created_at",
|
||||
"updated_at",
|
||||
@@ -79,6 +78,19 @@ class ActivationCodeAdmin(admin.ModelAdmin):
|
||||
|
||||
actions = ["recompute_current_uses"]
|
||||
|
||||
def get_readonly_fields(self, request, obj=None):
|
||||
"""Make `code` readonly when editing an existing ActivationCode.
|
||||
|
||||
When obj is None (creation form), `code` remains editable. When obj is
|
||||
provided (editing), add `code` to readonly fields so it cannot be
|
||||
changed after creation.
|
||||
"""
|
||||
# Start from the configured readonly_fields to preserve other read-only fields
|
||||
ro_fields = list(self.readonly_fields)
|
||||
if obj is not None:
|
||||
ro_fields.append("code")
|
||||
return tuple(ro_fields)
|
||||
|
||||
def usage_display(self, obj):
|
||||
"""Display usage statistics."""
|
||||
max_uses = obj.max_uses if obj.max_uses > 0 else "∞"
|
||||
|
||||
@@ -54,6 +54,12 @@ class Migration(migrations.Migration):
|
||||
help_text="The activation code that users will enter",
|
||||
max_length=50,
|
||||
unique=True,
|
||||
validators=[
|
||||
django.core.validators.RegexValidator(
|
||||
message="Code must be alphanumeric and contain no spaces or special characters",
|
||||
regex="^[A-Z0-9]+$",
|
||||
)
|
||||
],
|
||||
verbose_name="activation code",
|
||||
),
|
||||
),
|
||||
|
||||
@@ -7,6 +7,7 @@ import secrets
|
||||
import string
|
||||
|
||||
from django.core.exceptions import ValidationError
|
||||
from django.core.validators import RegexValidator
|
||||
from django.db import IntegrityError, models, transaction
|
||||
from django.utils import timezone
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
@@ -37,6 +38,12 @@ class ActivationCode(BaseModel):
|
||||
max_length=50,
|
||||
unique=True,
|
||||
default=generate_activation_code,
|
||||
validators=[
|
||||
RegexValidator(
|
||||
regex=r"^[A-Z0-9]+$",
|
||||
message=_("Code must be alphanumeric and contain no spaces or special characters"),
|
||||
)
|
||||
],
|
||||
)
|
||||
|
||||
max_uses = models.PositiveIntegerField(
|
||||
|
||||
Reference in New Issue
Block a user