prices
modulepip install django-prices
django_prices
to your INSTALLED_APPS
at settings.py
enmerkar
instructions and update both your INSTALLED_APPS
and MIDDLEWARE_CLASSES
.Provides support for models:
from django.db import models
from django_prices.models import MoneyField, TaxedMoneyField
class Model(models.Model):
currency = models.CharField(max_length=3, default="BTC")
price_net_amount = models.DecimalField(max_digits=9, decimal_places=2, default="5")
price_net = MoneyField(amount_field="price_net_amount", currency_field="currency")
price_gross_amount = models.DecimalField(
max_digits=9, decimal_places=2, default="5"
)
price_gross = MoneyField(
amount_field="price_gross_amount", currency_field="currency"
)
price = TaxedMoneyField(
net_amount_field="price_net_amount",
gross_amount_field="price_gross_amount",
currency="currency",
)
And forms:
from django import forms
from django_prices.forms import MoneyField
AVAILABLE_CURRENCIES = ["BTC", "USD"]
class ProductForm(forms.Form):
name = forms.CharField(label="Name")
price_net = MoneyField(label="net", available_currencies=AVAILABLE_CURRENCIES)
And validators:
from django import forms
from prices.forms import Money
from django_prices.forms import MoneyField
from django_prices.validators import (
MaxMoneyValidator, MinMoneyValidator, MoneyPrecisionValidator)
class DonateForm(forms.Form):
donator_name = forms.CharField(label="Your name")
donation = MoneyField(
label="net",
available_currencies=["BTC", "USD"],
max_digits=9,
decimal_places=2,
validators=[
MoneyPrecisionValidator(),
MinMoneyValidator(Money(5, "USD")),
MaxMoneyValidator(Money(500, "USD")),
],
)
It also provides support for templates:
{% load prices %}
<p>Price: {{ foo.price.gross|amount }} ({{ foo.price.net|amount }} + {{ foo.price.tax|amount }} tax)</p>
You can also use HTML output from prices
template tags, they will wrap currency symbol in a <span>
element:
{% load prices %}
<p>Price: {{ foo.price.gross|amount:'html' }} ({{ foo.price.net|amount:'html' }} + {{ foo.price.tax|amount:'html' }} tax)</p>
It will be rendered as a following structure (for example with English locale):
<span class="currency">$</span>15.00
Version 2.0 introduces major changes to how prices data is stored in models, enabling setting price's currency per model instance.
Steps to migrate:
In your forms:
currency
argumentavailable_currencies
with available choices.If the form specified MoneyFields
in fields
option, replace those with explicit declarations instead:
AVAILABLE_CURRENCIES = [("BTC", "bitcoins"), ("USD", "US dollar")]
class ModelForm(forms.ModelForm):
class Meta:
model = models.Model
fields = []
price_net = MoneyField(available_currencies=AVAILABLE_CURRENCIES)
In your models using MoneyField
:
MoneyField
class with DecimalField
currency
argument from themChange default
from Money instance to value acceptable by Decimal field
Example of code:
price_net = MoneyField(
"net", currency="BTC", default=Money("5", "BTC"), max_digits=9, decimal_places=2
)
Updated code:
price_net = models.DecimalField("net", default="5", max_digits=9, decimal_places=2)
In your migration files:
MoneyField
class with DecimalField
currency
argument from themChange default
from Money instance to value acceptable by Decimal field
field = django_prices.models.MoneyField(currency='BTC', decimal_places=2, default='5', max_digits=9, verbose_name='net')
Updated code:
field = models.DecimalField(decimal_places=2, default='5', max_digits=9, verbose_name='net')
Rename fields in models. Your old field will still store amount of money, so probably the best choice would be price_net_amount
instead price_net
.
All places which use Models and it's fields can prevent django app from even starting the code. Possible issues: code tries to access non existing fields. Exclude those fields for now from your ModelForms, Graphene types etc.
Run python manage.py makemigrations
. Make sure to do this step before adding new MoneyFields
to model! If not, django will generate delete/create
migrations instead of rename
.
Run python manage.py migrate
.
Update django-prices
.
Add models.CharField
for currency and MoneyField
to your models:
currency = models.CharField(max_length=3, default="BTC")
price_net_amount = models.DecimalField("net", default="5", max_digits=9, decimal_places=2)
price_net = MoneyField(amount_field="price_net_amount", currency_field="currency")
Run python manage.py makemigrations
and python manage.py migrate
.
Change TaxedMoneyField
declaration:
price = TaxedMoneyField(
net_amount_field="price_net_amount",
gross_amount_field="price_gross_amount",
currency="currency",
)
Remember to address changes in previously edited ModelForms