Skip to main content
https://api.travis-ci.org/5monkeys/django-bananas.svg?branch=master https://coveralls.io/repos/5monkeys/django-bananas/badge.svg?branch=master&service=github https://img.shields.io/pypi/v/django-bananas.svg

Install

django-bananas is on PyPI, so just run:

pip install django-bananas

Compatibility

Currently tested only for

  • Django 1.11-2.2 under Python 3.5-3.7

  • Django 3.0 under Python 3.6-3.7

pull requests welcome!

Examples

Models

TimeStampedModel

Abstract TimeStampedModel with date created/modified fields:

Use TimeStampedModel as base class for your model

from bananas.models import TimeStampedModel

class Book(TimeStampedModel):
    pass

the timestamps can be accessed on the model as

>>> book.date_created
>>> book.date_modified

UUIDModel

Abstract model that uses a Django 1.8 UUID field as the primary key.

from bananas.models import UUIDModel

class User(UUIDModel):
    display_name = models.CharField(max_length=255)
    email = models.EmailField()

>>> user.id
UUID('70cf1f46-2c79-4fc9-8cc8-523d67484182')

>>> user.pk
UUID('70cf1f46-2c79-4fc9-8cc8-523d67484182')

SecretField

Can be used to generate and store “safe” random bytes for authentication.

from bananas.models import SecretField

class User(models.Model):
    # Ask for 32 bytes and require 24 bytes from urandom
    token = SecretField(num_bytes=32, min_bytes=24)

>>> User.objects.create()  # Token is generated automatically
>>> user.token
'3076f884da827809e80ced236e8da20fa36d0c27dd036bdd4afbac34807e5cf1'

URLSecretField

An implementation of SecretField that generates an URL-safe base64 string instead of a hex representation of the random bytes.

from bananas.models import URLSecretField


class User(models.Model):
    # Generates an URL-safe base64 representation of the random value
    token = URLSecretField(num_bytes=32, min_bytes=24)

>>> user.token
'WOgrNwqFKOF_LsHorJy_hGpPepjvVH7Uar-4Z_K6DzU-'

ORM

New queryset.dicts() with field renaming through kwargs, and dot-dict style results:

from bananas.query import ExtendedQuerySet

class Book(TimeStampedModel):
    author = ForeignKey(Author)
    objects = Manager.from_queryset(ExtendedQuerySet)()

>>> book = Book.objects.dicts('id', author='author__name').first()
{'id': 1, 'author': 'Jonas'}
>>> book.author
'Jonas'

Admin

Custom django admin stylesheet.

# settings.py
INSTALLED_APPS = (
    'bananas',  # Needs to be before 'django.contrib.admin'
    'django.contrib.admin',
    ...
)

ADMIN = {
    'SITE_HEADER': 'Bananas',
    'SITE_TITLE': 'Bananas Admin',
    'INDEX_TITLE': 'Admin Panel',
    # 'BACKGROUND_COLOR': '#363c3f',
}
# your main urls.py
from bananas import admin

urlpatterns = [
    ...
    url(r'^admin/', include(admin.site.urls)),
]
# app/admin.py or something
from django.conf.urls import url
from bananas import admin

@admin.register
class MyAdminView(admin.AdminView):
    def get_urls(self):
        return [
            url(r'^custom/$',
                self.admin_view(self.custom_view)),
                # ^^ Note that the view is wrapped in self.admin_view.
                # Needed for permissions and to prevent any
                # threading issues.
        ]

    def get(self, request):
        return self.render('admin/template.html', {})

    def custom_view(self, request):
        return self.render('admin/custom.html', {})

Admin API

Django admin API for use with django-bananas.js (react admin site)

# app/admin.py or something
from bananas.admin.api.mixins import BananasAPI
from bananas.admin.api.schemas import schema
from bananas.admin.api.views import BananasAdminAPI
from bananas.lazy import lazy_title
from django.utils.translation import ugettext_lazy as _
from rest_framework import viewsets

class CustomAdminAPI(BananasAdminAPI):

    name = lazy_title(_("custom"))

    @schema(query_serializer=SomeSerializer, responses={200: SomeSerializer})
    def list(self, request):
        return ...

class SomeModelAdminAPI(BananasAPI, viewsets.ModelViewSet)

    serializer_class = SomeModelSerializer

    def list(self, request):
        return ...
# app/urls.py or something
from bananas.admin import api
from django.conf.urls import include, path

from .admin import CustomAdminAPI, SomeModelAdminAPI

api.register(CustomAdminAPI)
api.register(SomeModelAdminAPI)

urlpatterns = [
    path(r"^api/", include("bananas.admin.api.urls"))
]
# setting.py
ADMIN = {
   'API': {
      # Optional: override the default OpenAPI schemes
      'SCHEMES': ['https'],
   }
}

Database URLs

Parse database information from a URL, kind of like SQLAlchemy.

Engines

Currently supported engines are:

URI scheme

Engine

pgsql, postgres, postgresql

django.db.backends.postgresql_psycopg2

mysql

django.db.backends.mysql

oracle

django.db.backends.oracle

sqlite, sqlite3

django.db.backends.sqlite3

mysqlgis

django.contrib.gis.db.backends.mysql

oraclegis

django.contrib.gis.db.backends.oracle

postgis

django.contrib.gis.db.backends.postgis

spatialite

django.contrib.gis.db.backends.spatialite

You can add your own by running register(scheme, module_name) before parsing.

database_conf_from_url(url)

Return a django-style database configuration based on url.

param url:

Database URL

return:

Django-style database configuration dict

Example:

>>> from bananas.url import database_conf_from_url
>>> conf = database_conf_from_url(
...     'pgsql://joar:hunter2@5monkeys.se:4242/tweets/tweetschema'
...     '?hello=world')
>>> sorted(conf.items())  # doctest: +NORMALIZE_WHITESPACE
[('ENGINE', 'django.db.backends.postgresql_psycopg2'),
 ('HOST', '5monkeys.se'),
 ('NAME', 'tweets'),
 ('PARAMS', {'hello': 'world'}),
 ('PASSWORD', 'hunter2'),
 ('PORT', 4242),
 ('SCHEMA', 'tweetschema'),
 ('USER', 'joar')]

bananas.environment - Helpers to get setting values from environment variables

bananas.environment.env is a wrapper around os.environ, it provides the standard .get(key, value), method to get a value for a key, or a default if the key is not set - by default that default is None as you would expect. What is more useful is the additional type-parsing .get_* methods it provides:

  • get_bool

  • get_int

  • get_list, get_set, get_tuple

get_int:
>>> # env ONE=1
>>> env.get_int('ONE')
1
>>> env.get_int('TWO')  # Not set
None
>>> env.get_int('TWO', -1)  # Not set, default to -1
-1
get_bool:

returns True if the environment variable value is any of, case-insensitive:

  • "true"

  • "yes"

  • "on"

  • "1"

returns False if the environment variable value is any of, case-insensitive:

  • "false"

  • "no"

  • "off"

  • "0"

if the value is set to anything other than above, the default value will be returned instead.

e.g.:

>>> # env CAN_DO=1 NO_THANKS=false NO_HABLA=f4lse
>>> env.get_bool('CAN_DO')
True
>>> env.get_bool('NO_THANKS')
False
>>> env.get_bool('NO_HABLA')  # Set, but not valid
None
>>> env.get_bool('NO_HABLA', True)  # Set, but not valid, with default
True
>>> env.get_bool('IS_NONE')  # Not set
None
>>> env.get_bool('IS_NONE', False)  # Not set, default provided
False
get_tuple, get_list, get_set:

Returns a tuple, list or set of the environment variable string, split by the ascii comma character. e.g.:

>>> # env FOOS=foo,foo,bar
>>> get_list('FOO')
['foo', 'foo', 'bar']
>>> get_set('FOO')
set(['foo', 'bar'])

bananas.secrets - Helpers for getting secrets from files

Is useful for getting the content of secrets stored in files. One usecase is docker secrets.

BANANAS_SECRETS_DIR can be used to configure the directory that secrets live in. Defaults to /run/secrets/.

>>> from bananas import secrets

>>> secrets.get_secret("hemlis")
"topsecret"

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

django-bananas-1.5.1.tar.gz (41.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

django_bananas-1.5.1-py3-none-any.whl (47.3 kB view details)

Uploaded Python 3

File details

Details for the file django-bananas-1.5.1.tar.gz.

File metadata

  • Download URL: django-bananas-1.5.1.tar.gz
  • Upload date:
  • Size: 41.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.13.0 pkginfo/1.5.0.1 requests/2.22.0 setuptools/41.2.0 requests-toolbelt/0.9.1 tqdm/4.35.0 CPython/3.7.0

File hashes

Hashes for django-bananas-1.5.1.tar.gz
Algorithm Hash digest
SHA256 80e9c3aa398c6bdc44d9bcedfd40b58a4c21b6b7b0fcd855619053003af70274
MD5 2072366d282468793c5363f19217ecf9
BLAKE2b-256 df9fa77c94fb7902242609d6a0737171c62352c82db99200df59a11ecd3ef5e6

See more details on using hashes here.

File details

Details for the file django_bananas-1.5.1-py3-none-any.whl.

File metadata

  • Download URL: django_bananas-1.5.1-py3-none-any.whl
  • Upload date:
  • Size: 47.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.13.0 pkginfo/1.5.0.1 requests/2.22.0 setuptools/41.2.0 requests-toolbelt/0.9.1 tqdm/4.35.0 CPython/3.7.0

File hashes

Hashes for django_bananas-1.5.1-py3-none-any.whl
Algorithm Hash digest
SHA256 12498dfe758394dbd0c111e00f88d7a7a6a499838fb70fd5b8943e575875efe4
MD5 a5a7dd3e6c9df9235cdc3b6715192b97
BLAKE2b-256 f7d407b0bd4171a80ac948c62b61b95522b3e7de212edf0270a1db5ef06d1b1b

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page