如何在Django模型的models.ChoiceField中引入Babel内置货币列表
Got it, let's break down how to populate your Django ChoiceField with Babel's built-in currency list—this is a common use case, and Babel makes it pretty straightforward once you know the steps.
First, make sure you have the necessary packages installed:
pip install django babel
1. Import Required Modules
In your models.py file, import the Babel utilities we need, plus Django's model tools and the lazy function (to avoid premature evaluation issues):
from babel.numbers import get_currency_name, list_currencies from django.db import models from django.utils.functional import lazy
2. Create a Helper Function for Currency Choices
We'll write a function that fetches valid ISO 4217 currency codes, pairs them with human-readable names, and filters out obsolete currencies for relevance:
def get_currency_choices(locale="en_US"): # Fetch only active, non-obsolete currencies currency_codes = list_currencies(include_obsolete=False) # Sort codes alphabetically for better user experience sorted_codes = sorted(currency_codes) # Return tuples of (currency code, human-readable name) return [(code, get_currency_name(code, locale=locale)) for code in sorted_codes] # Use Django's lazy to delay evaluation until runtime (avoids module load errors) CURRENCY_CHOICES = lazy(get_currency_choices, list)()
3. Assign Choices to Your Model Field
Now you can use this generated list directly in your ChoiceField:
class YourModel(models.Model): currencies = models.ChoiceField( choices=CURRENCY_CHOICES, max_length=3, # ISO currency codes are always 3 characters long help_text="Select a currency", # Optional: set a default currency if needed default="USD" )
Bonus: Dynamic Choices for Multi-Language Apps
If your app supports multiple languages, you might want to show currency names in the user's preferred locale. Since model-level choices are static (or lazily evaluated once), override this logic in a form:
Form Implementation
from django import forms from .models import YourModel, get_currency_choices class YourModelForm(forms.ModelForm): class Meta: model = YourModel fields = ["currencies"] def __init__(self, *args, **kwargs): # Extract the request to access the user's locale request = kwargs.pop("request", None) super().__init__(*args, **kwargs) if request: # Use the user's language code from the request user_locale = request.LANGUAGE_CODE self.fields["currencies"].choices = get_currency_choices(locale=user_locale)
View Usage
Pass the request to the form when initializing it in your view:
from django.shortcuts import render from .forms import YourModelForm def create_currency_entry(request): form = YourModelForm(request=request) return render(request, "your_template.html", {"form": form})
Quick Notes
- Babel's
get_currency_namefalls back to the currency code if a localized name isn't available for a given locale. - Adjust the default locale in
get_currency_choicesto match your app's primary language if needed. - The
max_length=3is safe because all valid ISO 4217 currency codes are exactly 3 characters.
内容的提问来源于stack exchange,提问作者Philip Mutua

