django-pwyw
Pay‑what‑you‑want (PWYW) utilities for Django projects. This app provides models and helpers to let your users choose their own price, maintain balance transactions, and manage recurring subscriptions with flexible billing periods.
Features
- Price suggestions you can display in your UI (
PriceSuggestion) - Simple user subscription model with daily/weekly/monthly/quarterly/yearly billing (
Subscription) - Balance transactions with deposits, debits and adjustments (
BalanceTransaction) - Sensible defaults and i18n labels via Django’s translation utilities
Quick start
- Install
pip install django-pwyw
If you are working from source, install the project in editable mode:
pip install -e .
- Add to
INSTALLED_APPSin your Django settings:
INSTALLED_APPS = [
# ...
"pwyw",
]
- Apply migrations
python manage.py makemigrations
python manage.py migrate
- Optional settings
PWYW_CURRENCY— currency code used in string representations (default:"EUR").
Add to your Django settings if you want to override the default:
PWYW_CURRENCY = "USD"
Usage overview
Price suggestions
from pwyw.models import PriceSuggestion
# Pre-populate a few suggestions to show in your UI
PriceSuggestion.objects.bulk_create([
PriceSuggestion(label="Minimum", amount="5.00", sort_order=10),
PriceSuggestion(label="Recommended", amount="12.00", sort_order=20),
PriceSuggestion(label="Supporter", amount="20.00", sort_order=30),
])
active = PriceSuggestion.objects.filter(is_active=True).order_by("sort_order", "amount")
Subscriptions
from decimal import Decimal
from django.contrib.auth import get_user_model
from pwyw.models import Subscription
User = get_user_model()
user = User.objects.first()
sub = Subscription.objects.create(
user=user,
amount=Decimal("10.00"),
billing_period=Subscription.BillingPeriodChoices.MONTHLY,
)
# Read-only generated field for active status (computed from `expired_at`)
sub.is_active # True/False
Subscriptions enforce amount != 0 and will expire any previous open subscription for the same user when saving a new one.
Balance transactions
from decimal import Decimal
from pwyw.models import BalanceTransaction
txn = BalanceTransaction.objects.create(
user=user,
amount=Decimal("25.00"),
type=BalanceTransaction.TypeChoices.TYPE_DEPOSIT,
approved=True,
note="Initial top-up",
)
current = BalanceTransaction.balance_for(user)
Per-product pricing
Need a tenant to choose a separate price per product instead of one global or per-tenant amount?
Subclass the abstract bases in pwyw.base and add a product foreign key to _sibling_filter().
See Advanced: custom owners & per-product pricing.
Demo & docs
- Demo templates live under
demo/and may help you scaffold a simple dashboard. - Developer docs are in
docs/(seemkdocs.yml). If you use MkDocs, you can preview docs locally with:
pip install mkdocs
mkdocs serve
Development
Clone the repo and set up a virtual environment. Then:
pip install -e .[dev]
Run tests with pytest:
pytest -q
Run type checks (if you use mypy and django-stubs):
mypy
Project layout
src/pwyw/— Django app code (models, forms, utils, URLs)tests/— test suite (pytest)docs/— documentation source (MkDocs)demo/— demo assets/templatesChangelog.md— release notes
Changelog
See Changelog.md for notable changes between versions.
Compatibility
- Python 3.12+
- Django 5.x (and Django ORM features like
GeneratedField)
License
django-pwyw is licensed under the AGPL v3 or later.
In short: you can use it for free, even in commercial projects, but if you change/adapt the code, you'll have to provide the source code of the library (only your django-pwyw fork!).
Contributing
Issues and pull requests are welcome. Please include tests for any behavior changes. Use Black for formatting the code.
Metadata
Release files for django_pwyw 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| django_pwyw-0.1.1.tar.gz | 34.2 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| django_pwyw-0.1.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 65.1 kB
Release files / django_pwyw-0.1.1.tar.gz
| Download URL | django_pwyw-0.1.1.tar.gz |
|---|---|
| Size | 34.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
472b623c1697715e495abf46aae1c418da944f1290aafc6b3568a7da4b00dc87
|
|
BLAKE2b-256 checksum How to use checksums |
a75ae2fdced4322f366fd0a40c142a944cee0cd9b80e01db011e2c93e8dfc128
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.9.17 {"installer":{"name":"uv","version":"0.9.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"KDE neon","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / django_pwyw-0.1.1-py3-none-any.whl
| Download URL | django_pwyw-0.1.1-py3-none-any.whl |
|---|---|
| Size | 30.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
50086d3ccf938087f99d51400ce8198b97984a9e46d5b1649fae092f999b6eff
|
|
BLAKE2b-256 checksum How to use checksums |
e09199f752b52f92c86c8ce02de28b30a98c9c0c9f72c7c31533e499c248c239
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.9.17 {"installer":{"name":"uv","version":"0.9.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"KDE neon","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Security for django_pwyw 0.1.1
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.