Code reference › models › common

class

GenerateCode

pretalx.common.models.mixins.GenerateCode source

Generates a random code on first save.

Omits some character pairs because they are hard to read/differentiate: 1/I, O/0, 2/Z, 4/A, 5/S, 6/G. Configure via class attributes.

Attributes 4

code_charset['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'K', 'L', 'M', 'N', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '3', '7', '8', '9']
code_length6
code_property'code'
code_scope()

Methods 2

Defined here

assign_code(length=None)source
def assign_code(self, length=None):
    length = length or self.code_length
    while True:
        code = self.generate_code(length=length)
        filter_kwargs = {f"{self.code_property}__iexact": code}
        for field in self.code_scope:
            filter_kwargs[field] = getattr(self, field)
        with scopes_disabled():
            if not self.__class__.objects.filter(**filter_kwargs).exists():
                setattr(self, self.code_property, code)
                return
save(*args, **kwargs)source
def save(self, *args, **kwargs):
    if getattr(self, self.code_property, None):
        return super().save(*args, **kwargs)

    # Auto-generate code with retry loop to handle unlikely race conditions
    if "update_fields" in kwargs:
        kwargs["update_fields"] = {self.code_property}.union(
            kwargs["update_fields"]
        )
    for attempt in range(
        3
    ):  # pragma: no branch -- loop always exits via return or raise
        self.assign_code()
        try:
            with transaction.atomic():
                return super().save(*args, **kwargs)
        except IntegrityError:
            if attempt == 2:
                raise
            setattr(self, self.code_property, None)