Git Product home page Git Product logo

django-prices's Introduction

django-prices: Django fields for the prices module

Build Status codecov.io

Installation

  • pip install django-prices
  • Add django_prices to your INSTALLED_APPS at settings.py
  • Follow django-babel instructions and update both your INSTALLED_APPS and MIDDLEWARE_CLASSES.

Features

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

How to migrate to django-prices 2.0

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:

  1. In your forms:

    • remove the currency argument
    • add available_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)
  2. In your models using MoneyField:

    • Replace all occurrences of the MoneyField class with DecimalField

    • Remove the currency argument from them

    • Change 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)
  3. In your migration files:

    • Replace all occurrences of the MoneyField class with DecimalField

    • Remove the currency argument from them

    • Change 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')
  4. 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.

  5. 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.

  6. 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.

  7. Run python manage.py migrate.

  8. Update django-prices.

  9. 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")
  10. Run python manage.py makemigrations and python manage.py migrate.

  11. Change TaxedMoneyField declaration:

    price = TaxedMoneyField(
        net_amount_field="price_net_amount",
        gross_amount_field="price_gross_amount",
        currency="currency",
    )
  12. Remember to address changes in previously edited ModelForms

django-prices's People

Contributors

akjanik avatar artursmet avatar bharathwaaj avatar bogdal avatar derenio avatar gregmuellegger avatar itbabu avatar koradon avatar krzysztofwolski avatar kwaidan00 avatar maarcingebala avatar marekbrzoska avatar mitcom avatar mkalinowski avatar mociepka avatar patrys avatar rafalp avatar szewczykmira avatar tungd avatar zagrebelin avatar

Stargazers

 avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.