Django Bananas - Django extensions the monkey way
Project description
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"
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Hashes for django_bananas-1.5.1-py3-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 12498dfe758394dbd0c111e00f88d7a7a6a499838fb70fd5b8943e575875efe4 |
|
MD5 | a5a7dd3e6c9df9235cdc3b6715192b97 |
|
BLAKE2b-256 | f7d407b0bd4171a80ac948c62b61b95522b3e7de212edf0270a1db5ef06d1b1b |