Skip to content

Choices

Django choice field definitions for various data types.

This module provides a collection of choice classes for use with Django models and forms. Each class inherits from BaseChoices and provides standardized options for different data types and business domains.

Categories
  • Generic: Basic choice types like boolean, time frequency, etc.
  • Person: Demographic and personal information choices
  • Payment: Payment and transaction related choices
Example

from django_util.choices import TimeFrequencyChoices

class Subscription(models.Model): frequency = models.CharField( max_length=50, choices=TimeFrequencyChoices.choices, default=TimeFrequencyChoices.DEFAULT )

BooleanChoices

Bases: ChoicesMixin, TextChoices

Boolean choice options with an empty default.

Source code in django_util/choices.py
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
class BooleanChoices(ChoicesMixin, models.TextChoices):
    """Boolean choice options with an empty default."""

    DEFAULT = "", _("---")
    YES = "TRUE", _("Yes")
    NO = "FALSE", _("No")

    @classmethod
    def to_python(cls, value: str) -> Optional[bool]:
        """Convert string value to Python boolean."""
        if value == cls.YES:
            return True
        if value == cls.NO:
            return False
        return None

to_python(value) classmethod

Convert string value to Python boolean.

Source code in django_util/choices.py
176
177
178
179
180
181
182
183
@classmethod
def to_python(cls, value: str) -> Optional[bool]:
    """Convert string value to Python boolean."""
    if value == cls.YES:
        return True
    if value == cls.NO:
        return False
    return None

ChoicesMixin

Mixin providing utility methods for Django choice classes.

This mixin adds common functionality to choice classes including value validation, label retrieval, and choice list manipulation.

Example

class MyChoices(ChoicesMixin, models.TextChoices): DEFAULT = "", ("---") OPTION_A = "A", ("Option A") OPTION_B = "B", _("Option B")

# Now has access to utility methods:
MyChoices.is_valid("A")  # Returns True
MyChoices.get_label("B")  # Returns "Option B"
Source code in django_util/choices.py
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
class ChoicesMixin:
    """Mixin providing utility methods for Django choice classes.

    This mixin adds common functionality to choice classes including value validation,
    label retrieval, and choice list manipulation.

    Example:
        class MyChoices(ChoicesMixin, models.TextChoices):
            DEFAULT = "", _("---")
            OPTION_A = "A", _("Option A")
            OPTION_B = "B", _("Option B")

            # Now has access to utility methods:
            MyChoices.is_valid("A")  # Returns True
            MyChoices.get_label("B")  # Returns "Option B"
    """

    @classmethod
    def get_values(cls) -> Set[str]:
        """Return set of all valid choice values.

        Returns:
            Set[str]: A set containing all possible choice values excluding labels.
        """
        return {choice[0] for choice in cls.choices}

    @classmethod
    def get_labels(cls) -> Dict[str, str]:
        """Return mapping of values to their display labels."""
        return {choice[0]: choice[1] for choice in cls.choices}

    @classmethod
    def is_valid(cls, value: str) -> bool:
        """Check if a value is valid for this choice set.

        Args:
            value (str): The choice value to validate.

        Returns:
            bool: True if the value is valid, False otherwise.
        """
        return value in cls.get_values()

    @classmethod
    def get_label(cls, value: str) -> Optional[str]:
        """Get display label for a value."""
        return cls.get_labels().get(value)

    @classmethod
    def exclude_default(cls) -> List[Tuple[str, str]]:
        """Return choices without the DEFAULT option."""
        return [(k, v) for k, v in cls.choices if k != ""]

exclude_default() classmethod

Return choices without the DEFAULT option.

Source code in django_util/choices.py
145
146
147
148
@classmethod
def exclude_default(cls) -> List[Tuple[str, str]]:
    """Return choices without the DEFAULT option."""
    return [(k, v) for k, v in cls.choices if k != ""]

get_label(value) classmethod

Get display label for a value.

Source code in django_util/choices.py
140
141
142
143
@classmethod
def get_label(cls, value: str) -> Optional[str]:
    """Get display label for a value."""
    return cls.get_labels().get(value)

get_labels() classmethod

Return mapping of values to their display labels.

Source code in django_util/choices.py
123
124
125
126
@classmethod
def get_labels(cls) -> Dict[str, str]:
    """Return mapping of values to their display labels."""
    return {choice[0]: choice[1] for choice in cls.choices}

get_values() classmethod

Return set of all valid choice values.

Returns:

Type Description
Set[str]

Set[str]: A set containing all possible choice values excluding labels.

Source code in django_util/choices.py
114
115
116
117
118
119
120
121
@classmethod
def get_values(cls) -> Set[str]:
    """Return set of all valid choice values.

    Returns:
        Set[str]: A set containing all possible choice values excluding labels.
    """
    return {choice[0] for choice in cls.choices}

is_valid(value) classmethod

Check if a value is valid for this choice set.

Parameters:

Name Type Description Default
value str

The choice value to validate.

required

Returns:

Name Type Description
bool bool

True if the value is valid, False otherwise.

Source code in django_util/choices.py
128
129
130
131
132
133
134
135
136
137
138
@classmethod
def is_valid(cls, value: str) -> bool:
    """Check if a value is valid for this choice set.

    Args:
        value (str): The choice value to validate.

    Returns:
        bool: True if the value is valid, False otherwise.
    """
    return value in cls.get_values()

DataImportStrategy

Bases: ChoicesMixin, TextChoices

Strategy options for handling data imports when records already exist.

This class defines different approaches for handling duplicate data during import operations. Each strategy provides a different behavior for handling conflicts with existing records.

Attributes:

Name Type Description
FAIL str

Stops the import process if any existing records are found. Use when data integrity is critical and duplicates are not allowed.

REPLACE str

Overwrites any existing records with new data. Use when the imported data should be treated as the source of truth.

APPEND str

Adds new records while preserving existing ones. Use when maintaining historical data or collecting cumulative data.

Example

class DataImport(models.Model): strategy = models.CharField( max_length=50, choices=DataImportStrategy.choices, default=DataImportStrategy.FAIL, help_text="Strategy for handling existing records during import" )

Usage in import logic

if strategy == DataImportStrategy.FAIL: if existing_record: raise ImportError("Record already exists") elif strategy == DataImportStrategy.REPLACE: existing_record.update(new_data) elif strategy == DataImportStrategy.APPEND: create_new_record(new_data)

Source code in django_util/choices.py
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
class DataImportStrategy(ChoicesMixin, models.TextChoices):
    """Strategy options for handling data imports when records already exist.

    This class defines different approaches for handling duplicate data during import
    operations. Each strategy provides a different behavior for handling conflicts
    with existing records.

    Attributes:
        FAIL (str): Stops the import process if any existing records are found.
            Use when data integrity is critical and duplicates are not allowed.
        REPLACE (str): Overwrites any existing records with new data.
            Use when the imported data should be treated as the source of truth.
        APPEND (str): Adds new records while preserving existing ones.
            Use when maintaining historical data or collecting cumulative data.

    Example:
        class DataImport(models.Model):
            strategy = models.CharField(
                max_length=50,
                choices=DataImportStrategy.choices,
                default=DataImportStrategy.FAIL,
                help_text="Strategy for handling existing records during import"
            )

        # Usage in import logic
        if strategy == DataImportStrategy.FAIL:
            if existing_record:
                raise ImportError("Record already exists")
        elif strategy == DataImportStrategy.REPLACE:
            existing_record.update(new_data)
        elif strategy == DataImportStrategy.APPEND:
            create_new_record(new_data)
    """

    FAIL = "FAIL", _("Fail if exists")
    REPLACE = "REPLACE", _("Replace existing")
    APPEND = "APPEND", _("Append to existing")

FlatOrPercentChoices

Bases: ChoicesMixin, TextChoices

Choices for flat or percentage values.

Source code in django_util/choices.py
151
152
153
154
155
156
class FlatOrPercentChoices(ChoicesMixin, models.TextChoices):
    """Choices for flat or percentage values."""

    DEFAULT = "", _("---")
    FLAT = "FLAT", _("Flat")
    PERCENT = "PERCENT", _("Percent")

PaymentMethodTypeChoices

Bases: ChoicesMixin, TextChoices

Available payment method options.

Attributes:

Name Type Description
CREDIT_CARD str

Credit card payment method

DEBIT_CARD str

Debit card payment method

ELECTRONIC_BANK_TRANSFER str

Bank transfer payment method

PAYPAL str

PayPal payment method

APPLE_PAY str

Apple Pay payment method

GOOGLE_PAY str

Google Pay payment method

Source code in django_util/choices.py
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
class PaymentMethodTypeChoices(ChoicesMixin, models.TextChoices):
    """Available payment method options.

    Attributes:
        CREDIT_CARD (str): Credit card payment method
        DEBIT_CARD (str): Debit card payment method
        ELECTRONIC_BANK_TRANSFER (str): Bank transfer payment method
        PAYPAL (str): PayPal payment method
        APPLE_PAY (str): Apple Pay payment method
        GOOGLE_PAY (str): Google Pay payment method
    """

    DEFAULT = "", _("---")
    CREDIT_CARD = "CREDIT_CARD", _("Credit Card")
    DEBIT_CARD = "DEBIT_CARD", _("Debit Card")
    ELECTRONIC_BANK_TRANSFER = "BANK_TRANSFER", _("Bank Transfer")
    PAYPAL = "PAYPAL", _("PayPal")
    APPLE_PAY = "APPLE_PAY", _("Apple Pay")
    GOOGLE_PAY = "GOOGLE_PAY", _("Google Pay")

    @classmethod
    def requires_cvv(cls, method: str) -> bool:
        """Check if payment method requires CVV."""
        return method in PAYMENT_METHODS_REQUIRING_CVV

    @classmethod
    def requires_3ds(cls, method: str) -> bool:
        """Check if payment method requires 3D Secure."""
        return method in PAYMENT_METHODS_REQUIRING_3DS

    @classmethod
    def card_methods(cls) -> set:
        """Return all card-based payment methods."""
        return {cls.CREDIT_CARD, cls.DEBIT_CARD}

    @classmethod
    def digital_wallet_methods(cls) -> set:
        """Return all digital wallet payment methods."""
        return {cls.PAYPAL, cls.APPLE_PAY, cls.GOOGLE_PAY}

card_methods() classmethod

Return all card-based payment methods.

Source code in django_util/choices.py
405
406
407
408
@classmethod
def card_methods(cls) -> set:
    """Return all card-based payment methods."""
    return {cls.CREDIT_CARD, cls.DEBIT_CARD}

digital_wallet_methods() classmethod

Return all digital wallet payment methods.

Source code in django_util/choices.py
410
411
412
413
@classmethod
def digital_wallet_methods(cls) -> set:
    """Return all digital wallet payment methods."""
    return {cls.PAYPAL, cls.APPLE_PAY, cls.GOOGLE_PAY}

requires_3ds(method) classmethod

Check if payment method requires 3D Secure.

Source code in django_util/choices.py
400
401
402
403
@classmethod
def requires_3ds(cls, method: str) -> bool:
    """Check if payment method requires 3D Secure."""
    return method in PAYMENT_METHODS_REQUIRING_3DS

requires_cvv(method) classmethod

Check if payment method requires CVV.

Source code in django_util/choices.py
395
396
397
398
@classmethod
def requires_cvv(cls, method: str) -> bool:
    """Check if payment method requires CVV."""
    return method in PAYMENT_METHODS_REQUIRING_CVV

PersonBloodChoices

Bases: ChoicesMixin, TextChoices

Blood type classification options.

Attributes:

Name Type Description
A str

Blood type A

B str

Blood type B

AB str

Blood type AB

O str

Blood type O

OTHERS str

Other blood types

Source code in django_util/choices.py
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
class PersonBloodChoices(ChoicesMixin, models.TextChoices):
    """Blood type classification options.

    Attributes:
        A (str): Blood type A
        B (str): Blood type B
        AB (str): Blood type AB
        O (str): Blood type O
        OTHERS (str): Other blood types
    """

    DEFAULT = "", _("---")
    A = "A", _("A")
    B = "B", _("B")
    AB = "AB", _("AB")
    O = "O", _("O")
    OTHERS = "OTHERS", _("Others")

PersonEducationLevelChoices

Bases: ChoicesMixin, TextChoices

Academic achievement level classifications.

Represents different levels of academic achievement from high school through doctoral degrees.

References

https://study.com/different_degrees.html

Attributes:

Name Type Description
HIGH_SCHOOL str

High School diploma

ASSOCIATE str

Associate degree

BACHELOR str

Bachelor's degree

MASTER str

Master's degree

DOCTORAL str

Doctoral degree

OTHERS str

Other education levels

Source code in django_util/choices.py
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
class PersonEducationLevelChoices(ChoicesMixin, models.TextChoices):
    """Academic achievement level classifications.

    Represents different levels of academic achievement from high school through doctoral degrees.

    References:
        https://study.com/different_degrees.html

    Attributes:
        HIGH_SCHOOL (str): High School diploma
        ASSOCIATE (str): Associate degree
        BACHELOR (str): Bachelor's degree
        MASTER (str): Master's degree
        DOCTORAL (str): Doctoral degree
        OTHERS (str): Other education levels
    """

    DEFAULT = "", _("---")
    HIGH_SCHOOL = "HIGH_SCHOOL", _("High School")
    ASSOCIATE = "ASSOCIATE", _("Associate Degree")
    BACHELOR = "BACHELOR", _("Bachelor's Degree")
    MASTER = "MASTER", _("Master's Degree")
    DOCTORAL = "DOCTORAL", _("Doctoral Degree")
    OTHERS = "OTHERS", _("Others")

    @classmethod
    def get_education_years(cls, level: str) -> int:
        """Return typical years of education for given level."""
        return EDUCATION_LEVEL_YEARS.get(level, 0)

get_education_years(level) classmethod

Return typical years of education for given level.

Source code in django_util/choices.py
299
300
301
302
@classmethod
def get_education_years(cls, level: str) -> int:
    """Return typical years of education for given level."""
    return EDUCATION_LEVEL_YEARS.get(level, 0)

PersonEyeColorChoices

Bases: ChoicesMixin, TextChoices

Eye color classification options.

References

https://en.wikipedia.org/wiki/Eye_color#Eye_color_chart_(Martin_scale)

Attributes:

Name Type Description
AMBER str

Amber colored eyes

BLUE str

Blue colored eyes

BROWN str

Brown colored eyes

GREEN str

Green colored eyes

GREY str

Grey colored eyes

HAZEL str

Hazel colored eyes

RED str

Red colored eyes

OTHERS str

Other eye colors

Source code in django_util/choices.py
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
class PersonEyeColorChoices(ChoicesMixin, models.TextChoices):
    """Eye color classification options.

    References:
        https://en.wikipedia.org/wiki/Eye_color#Eye_color_chart_(Martin_scale)

    Attributes:
        AMBER (str): Amber colored eyes
        BLUE (str): Blue colored eyes
        BROWN (str): Brown colored eyes
        GREEN (str): Green colored eyes
        GREY (str): Grey colored eyes
        HAZEL (str): Hazel colored eyes
        RED (str): Red colored eyes
        OTHERS (str): Other eye colors
    """

    DEFAULT = "", _("---")
    AMBER = "AMBER", _("Amber")
    BLUE = "BLUE", _("Blue")
    BROWN = "BROWN", _("Brown")
    GREEN = "GREEN", _("Green")
    GREY = "GREY", _("Grey")
    HAZEL = "HAZEL", _("Hazel")
    RED = "RED", _("Red")
    OTHERS = "OTHERS", _("Others")

PersonGenderChoices

Bases: ChoicesMixin, TextChoices

Gender classification options.

Attributes:

Name Type Description
FEMALE str

Female gender

MALE str

Male gender

OTHERS str

Other gender identifications

Source code in django_util/choices.py
333
334
335
336
337
338
339
340
341
342
343
344
345
class PersonGenderChoices(ChoicesMixin, models.TextChoices):
    """Gender classification options.

    Attributes:
        FEMALE (str): Female gender
        MALE (str): Male gender
        OTHERS (str): Other gender identifications
    """

    DEFAULT = "", _("---")
    FEMALE = "FEMALE", _("Female")
    MALE = "MALE", _("Male")
    OTHERS = "OTHERS", _("Others")

PersonRaceChoices

Bases: ChoicesMixin, TextChoices

Racial and ethnic classification options.

References

https://grants.nih.gov/grants/guide/notice-files/not-od-15-089.html

Attributes:

Name Type Description
ASIAN str

Asian racial identification

BLACK str

Black or African American racial identification

HISPANIC str

Hispanic or Latino ethnic identification

INDIAN str

American Indian or Alaska Native racial identification

ISLANDER str

Native Hawaiian or Other Pacific Islander racial identification

WHITE str

White racial identification

OTHERS str

Other racial or ethnic identifications

Source code in django_util/choices.py
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
class PersonRaceChoices(ChoicesMixin, models.TextChoices):
    """Racial and ethnic classification options.

    References:
        https://grants.nih.gov/grants/guide/notice-files/not-od-15-089.html

    Attributes:
        ASIAN (str): Asian racial identification
        BLACK (str): Black or African American racial identification
        HISPANIC (str): Hispanic or Latino ethnic identification
        INDIAN (str): American Indian or Alaska Native racial identification
        ISLANDER (str): Native Hawaiian or Other Pacific Islander racial identification
        WHITE (str): White racial identification
        OTHERS (str): Other racial or ethnic identifications
    """

    DEFAULT = "", _("---")
    ASIAN = "ASIAN", _("Asian")
    BLACK = "BLACK", _("Black Or African American")
    HISPANIC = "HISPANIC", _("Hispanic Or Latino")
    INDIAN = "INDIAN", _("American Indian Or Alaska Native")
    ISLANDER = "ISLANDER", _("Native Hawaiian Or Other Pacific Islander")
    WHITE = "WHITE", _("White")
    OTHERS = "OTHERS", _("Others")

TaskStatusChoices

Bases: ChoicesMixin, TextChoices

Task processing status options.

Represents different states in a task's lifecycle from creation to completion.

Attributes:

Name Type Description
PENDING str

Task is waiting to be processed

IN_PROGRESS str

Task is currently being processed

COMPLETED str

Task has been successfully completed

FAILED str

Task has failed to complete

Source code in django_util/choices.py
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
class TaskStatusChoices(ChoicesMixin, models.TextChoices):
    """Task processing status options.

    Represents different states in a task's lifecycle from creation to completion.

    Attributes:
        PENDING (str): Task is waiting to be processed
        IN_PROGRESS (str): Task is currently being processed
        COMPLETED (str): Task has been successfully completed
        FAILED (str): Task has failed to complete
    """

    DEFAULT = "", _("---")
    PENDING = "PENDING", _("Pending")
    IN_PROGRESS = "IN_PROGRESS", _("In Progress")
    COMPLETED = "COMPLETED", _("Completed")
    FAILED = "FAILED", _("Failed")

    @classmethod
    def is_terminal_state(cls, status: str) -> bool:
        """Check if the status is in a terminal state (completed or failed)."""
        return status in {cls.COMPLETED, cls.FAILED}

    @classmethod
    def is_active_state(cls, status: str) -> bool:
        """Check if the status is in an active state (pending or in progress)."""
        return status in {cls.PENDING, cls.IN_PROGRESS}

is_active_state(status) classmethod

Check if the status is in an active state (pending or in progress).

Source code in django_util/choices.py
209
210
211
212
@classmethod
def is_active_state(cls, status: str) -> bool:
    """Check if the status is in an active state (pending or in progress)."""
    return status in {cls.PENDING, cls.IN_PROGRESS}

is_terminal_state(status) classmethod

Check if the status is in a terminal state (completed or failed).

Source code in django_util/choices.py
204
205
206
207
@classmethod
def is_terminal_state(cls, status: str) -> bool:
    """Check if the status is in a terminal state (completed or failed)."""
    return status in {cls.COMPLETED, cls.FAILED}

TimeFrequencyChoices

Bases: ChoicesMixin, TextChoices

Choices for time frequency options.

Source code in django_util/choices.py
159
160
161
162
163
164
165
166
class TimeFrequencyChoices(ChoicesMixin, models.TextChoices):
    """Choices for time frequency options."""

    DEFAULT = "", _("---")
    DAILY = "DAILY", _("Daily")
    WEEKLY = "WEEKLY", _("Weekly")
    MONTHLY = "MONTHLY", _("Monthly")
    YEARLY = "YEARLY", _("Yearly")

TransactionEventTypeChoices

Bases: ChoicesMixin, TextChoices

Transaction lifecycle event types.

Attributes:

Name Type Description
CREATED str

Transaction has been created

AUTHORIZED str

Transaction has been authorized

CAPTURED str

Transaction has been captured

REFUNDED str

Transaction has been refunded

FAILED str

Transaction has failed

Source code in django_util/choices.py
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
class TransactionEventTypeChoices(ChoicesMixin, models.TextChoices):
    """Transaction lifecycle event types.

    Attributes:
        CREATED (str): Transaction has been created
        AUTHORIZED (str): Transaction has been authorized
        CAPTURED (str): Transaction has been captured
        REFUNDED (str): Transaction has been refunded
        FAILED (str): Transaction has failed
    """

    DEFAULT = "", _("---")
    CREATED = "CREATED", _("Created")
    AUTHORIZED = "AUTHORIZED", _("Authorized")
    CAPTURED = "CAPTURED", _("Captured")
    REFUNDED = "REFUNDED", _("Refunded")
    FAILED = "FAILED", _("Failed")

TransactionGatewayChoices

Bases: ChoicesMixin, TextChoices

Supported payment processing gateways.

Attributes:

Name Type Description
ADYEN str

Adyen payment gateway

ALIPAY str

Alipay payment gateway

AMAZON str

Amazon payment gateway

AUTHORIZE str

Authorize.net payment gateway

BRAINTREE str

Braintree payment gateway

CYBERSOURCE str

Cybersource payment gateway

INGENICO str

Ingenico payment gateway

PAYPAL str

PayPal payment gateway

SQUARE str

Square payment gateway

STRIPE str

Stripe payment gateway

WEPAY str

WePay payment gateway

WORLDPAY str

Worldpay payment gateway

Source code in django_util/choices.py
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
class TransactionGatewayChoices(ChoicesMixin, models.TextChoices):
    """Supported payment processing gateways.

    Attributes:
        ADYEN (str): Adyen payment gateway
        ALIPAY (str): Alipay payment gateway
        AMAZON (str): Amazon payment gateway
        AUTHORIZE (str): Authorize.net payment gateway
        BRAINTREE (str): Braintree payment gateway
        CYBERSOURCE (str): Cybersource payment gateway
        INGENICO (str): Ingenico payment gateway
        PAYPAL (str): PayPal payment gateway
        SQUARE (str): Square payment gateway
        STRIPE (str): Stripe payment gateway
        WEPAY (str): WePay payment gateway
        WORLDPAY (str): Worldpay payment gateway
    """

    DEFAULT = "", _("---")
    ADYEN = "ADYEN", _("Adyen")
    ALIPAY = "ALIPAY", _("Alipay")
    AMAZON = "AMAZON", _("Amazon")
    AUTHORIZE = "AUTHORIZE", _("Authorize")
    BRAINTREE = "BRAINTREE", _("Braintree")
    CYBERSOURCE = "CYBERSOURCE", _("Cybersource")
    INGENICO = "INGENICO", _("Ingenico")
    PAYPAL = "PAYPAL", _("Paypal")
    SQUARE = "SQUARE", _("Square")
    STRIPE = "STRIPE", _("Stripe")
    WEPAY = "WEPAY", _("Wepay")
    WORLDPAY = "WORLDPAY", _("Worldpay")

TransactionStateChoices

Bases: ChoicesMixin, TextChoices

Transaction processing state options.

Represents the various states a transaction can be in during its lifecycle, from initiation to completion. Implements a state machine pattern where transitions between states are strictly controlled.

References

https://stripe.com/docs/payments/intents#intent-statuses

Attributes:

Name Type Description
REQUIRES_PAYMENT_METHOD str

Initial state when payment method is needed

REQUIRES_CONFIRMATION str

Payment method received, awaiting confirmation

REQUIRES_ACTION str

Additional user action needed (e.g., 3DS verification)

PROCESSING str

Transaction is being processed by payment provider

CANCEL str

Terminal state indicating cancelled transaction

SUCCESS str

Terminal state indicating successful completion

Example

Check if a state transition is valid

if TransactionStateChoices.can_transition_to( "REQUIRES_PAYMENT_METHOD", "REQUIRES_CONFIRMATION" ): # Perform transition

Source code in django_util/choices.py
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
class TransactionStateChoices(ChoicesMixin, models.TextChoices):
    """Transaction processing state options.

    Represents the various states a transaction can be in during its lifecycle,
    from initiation to completion. Implements a state machine pattern where
    transitions between states are strictly controlled.

    References:
        https://stripe.com/docs/payments/intents#intent-statuses

    Attributes:
        REQUIRES_PAYMENT_METHOD (str): Initial state when payment method is needed
        REQUIRES_CONFIRMATION (str): Payment method received, awaiting confirmation
        REQUIRES_ACTION (str): Additional user action needed (e.g., 3DS verification)
        PROCESSING (str): Transaction is being processed by payment provider
        CANCEL (str): Terminal state indicating cancelled transaction
        SUCCESS (str): Terminal state indicating successful completion

    Example:
        # Check if a state transition is valid
        if TransactionStateChoices.can_transition_to(
            "REQUIRES_PAYMENT_METHOD",
            "REQUIRES_CONFIRMATION"
        ):
            # Perform transition
    """

    DEFAULT = "", _("---")
    REQUIRES_PAYMENT_METHOD = "REQUIRES_PAYMENT_METHOD", _("Requires Payment Method")
    REQUIRES_CONFIRMATION = "REQUIRES_CONFIRMATION", _("Requires Confirmation")
    REQUIRES_ACTION = "REQUIRES_ACTION", _("Requires Action")
    PROCESSING = "PROCESSING", _("Processing")
    CANCEL = "CANCEL", _("Cancel")
    SUCCESS = "SUCCESS", _("Success")

    @classmethod
    def can_transition_to(cls, current_state: str, new_state: str) -> bool:
        """Validate if a state transition is allowed.

        Args:
            current_state (str): The current transaction state
            new_state (str): The proposed new state

        Returns:
            bool: True if the transition is allowed, False otherwise

        Example:
            >>> TransactionStateChoices.can_transition_to("PROCESSING", "SUCCESS")
            True
            >>> TransactionStateChoices.can_transition_to("SUCCESS", "PROCESSING")
            False
        """
        return new_state in TRANSACTION_STATE_TRANSITIONS.get(current_state, set())

can_transition_to(current_state, new_state) classmethod

Validate if a state transition is allowed.

Parameters:

Name Type Description Default
current_state str

The current transaction state

required
new_state str

The proposed new state

required

Returns:

Name Type Description
bool bool

True if the transition is allowed, False otherwise

Example

TransactionStateChoices.can_transition_to("PROCESSING", "SUCCESS") True TransactionStateChoices.can_transition_to("SUCCESS", "PROCESSING") False

Source code in django_util/choices.py
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
@classmethod
def can_transition_to(cls, current_state: str, new_state: str) -> bool:
    """Validate if a state transition is allowed.

    Args:
        current_state (str): The current transaction state
        new_state (str): The proposed new state

    Returns:
        bool: True if the transition is allowed, False otherwise

    Example:
        >>> TransactionStateChoices.can_transition_to("PROCESSING", "SUCCESS")
        True
        >>> TransactionStateChoices.can_transition_to("SUCCESS", "PROCESSING")
        False
    """
    return new_state in TRANSACTION_STATE_TRANSITIONS.get(current_state, set())

TransactionTypeChoices

Bases: ChoicesMixin, TextChoices

Transaction classification options.

Attributes:

Name Type Description
PAYMENT str

Standard payment transaction

REFUND str

Refund transaction

ADJUSTMENT str

Adjustment transaction

COUPON str

Coupon application transaction

PRORATION str

Proration transaction

Source code in django_util/choices.py
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
class TransactionTypeChoices(ChoicesMixin, models.TextChoices):
    """Transaction classification options.

    Attributes:
        PAYMENT (str): Standard payment transaction
        REFUND (str): Refund transaction
        ADJUSTMENT (str): Adjustment transaction
        COUPON (str): Coupon application transaction
        PRORATION (str): Proration transaction
    """

    DEFAULT = "", _("---")
    PAYMENT = "PAYMENT", _("Payment")
    REFUND = "REFUND", _("Refund")
    ADJUSTMENT = "ADJUSTMENT", _("Adjustment")
    COUPON = "COUPON", _("Coupon")
    PRORATION = "PRORATION", _("Proration")

    @classmethod
    def affects_balance(cls, trans_type: str) -> bool:
        """Check if transaction type affects account balance."""
        return trans_type in TRANSACTION_TYPE_AFFECTS_BALANCE

    @classmethod
    def requires_processing(cls, trans_type: str) -> bool:
        """Check if transaction type requires payment processing."""
        return trans_type in TRANSACTION_TYPE_REQUIRES_PROCESSING

affects_balance(trans_type) classmethod

Check if transaction type affects account balance.

Source code in django_util/choices.py
522
523
524
525
@classmethod
def affects_balance(cls, trans_type: str) -> bool:
    """Check if transaction type affects account balance."""
    return trans_type in TRANSACTION_TYPE_AFFECTS_BALANCE

requires_processing(trans_type) classmethod

Check if transaction type requires payment processing.

Source code in django_util/choices.py
527
528
529
530
@classmethod
def requires_processing(cls, trans_type: str) -> bool:
    """Check if transaction type requires payment processing."""
    return trans_type in TRANSACTION_TYPE_REQUIRES_PROCESSING