Skip to content

Commit

Permalink
Released package.
Browse files Browse the repository at this point in the history
  • Loading branch information
fabiocaccamo committed Feb 13, 2020
1 parent ab14ce8 commit d920aed
Show file tree
Hide file tree
Showing 33 changed files with 1,092 additions and 1 deletion.
108 changes: 108 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
sudo: required
language: python
python: 3.5
cache: pip
env:
- TOX_ENV=py35-dj18-sqlite
- TOX_ENV=py35-dj18-postgres
- TOX_ENV=py35-dj19-sqlite
- TOX_ENV=py35-dj19-postgres
- TOX_ENV=py35-dj110-sqlite
- TOX_ENV=py35-dj110-postgres
- TOX_ENV=py35-dj111-sqlite
- TOX_ENV=py35-dj111-postgres
- TOX_ENV=py35-dj20-sqlite
- TOX_ENV=py35-dj20-postgres
- TOX_ENV=py35-dj21-sqlite
- TOX_ENV=py35-dj21-postgres
# - TOX_ENV=py35-dj22-sqlite
- TOX_ENV=py35-dj22-postgres
matrix:
include:
- python: "3.6"
env: TOX_ENV=py36-dj111-sqlite
- python: "3.6"
env: TOX_ENV=py36-dj111-postgres
- python: "3.6"
env: TOX_ENV=py36-dj20-sqlite
- python: "3.6"
env: TOX_ENV=py36-dj20-postgres
- python: "3.6"
env: TOX_ENV=py36-dj21-sqlite
- python: "3.6"
env: TOX_ENV=py36-dj21-postgres
- python: "3.6"
env: TOX_ENV=py36-dj22-sqlite
- python: "3.6"
env: TOX_ENV=py36-dj22-postgres
- python: "3.6"
env: TOX_ENV=py36-dj30-sqlite
- python: "3.6"
env: TOX_ENV=py36-dj30-postgres
- python: "3.6"
env: TOX_ENV=py36-djmaster-sqlite
- python: "3.6"
env: TOX_ENV=py36-djmaster-postgres
- python: "3.7"
dist: xenial
env: TOX_ENV=py37-dj20-sqlite
- python: "3.7"
dist: xenial
env: TOX_ENV=py37-dj20-postgres
- python: "3.7"
dist: xenial
env: TOX_ENV=py37-dj21-sqlite
- python: "3.7"
dist: xenial
env: TOX_ENV=py37-dj21-postgres
- python: "3.7"
dist: xenial
env: TOX_ENV=py37-dj22-sqlite
- python: "3.7"
dist: xenial
env: TOX_ENV=py37-dj22-postgres
- python: "3.7"
dist: xenial
env: TOX_ENV=py37-dj30-sqlite
- python: "3.7"
dist: xenial
env: TOX_ENV=py37-dj30-postgres
- python: "3.7"
dist: xenial
env: TOX_ENV=py37-djmaster-sqlite
- python: "3.7"
dist: xenial
env: TOX_ENV=py37-djmaster-postgres
- python: "3.8"
dist: xenial
env: TOX_ENV=py38-dj22-sqlite
- python: "3.8"
dist: xenial
env: TOX_ENV=py38-dj22-postgres
- python: "3.8"
dist: xenial
env: TOX_ENV=py38-dj30-sqlite
- python: "3.8"
dist: xenial
env: TOX_ENV=py38-dj30-postgres
- python: "3.8"
dist: xenial
env: TOX_ENV=py38-djmaster-sqlite
- python: "3.8"
dist: xenial
env: TOX_ENV=py38-djmaster-postgres
allow_failures:
- env: TOX_ENV=py36-djmaster-sqlite
- env: TOX_ENV=py36-djmaster-postgres
- env: TOX_ENV=py37-djmaster-sqlite
- env: TOX_ENV=py37-djmaster-postgres
- env: TOX_ENV=py38-djmaster-sqlite
- env: TOX_ENV=py38-djmaster-postgres
install:
- pip install tox
services:
- postgresql
before_script:
- psql -c 'create database extra_settings;' -U postgres
script:
- tox -e $TOX_ENV
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Changelog
All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [0.1.0](https://github.com/fabiocaccamo/django-extra-settings/releases/tag/0.1.0) - 2020-02-13
- Released package, installation `pip install django-extra-settings`.
File renamed without changes.
4 changes: 4 additions & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
include LICENSE.txt
include README.md
recursive-include extra_settings *
recursive-exclude * *.pyc __pycache__ .DS_Store
78 changes: 77 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,78 @@
[![](https://img.shields.io/pypi/pyversions/django-extra-settings.svg?color=3776AB&logo=python&logoColor=white)](https://www.python.org/)
[![](https://img.shields.io/pypi/djversions/django-extra-settings?color=0C4B33&logo=django&logoColor=white&label=django)](https://www.djangoproject.com/)

[![](https://img.shields.io/pypi/v/django-extra-settings.svg?color=blue&logo=pypi&logoColor=white)](https://pypi.org/project/django-extra-settings/)
[![](https://pepy.tech/badge/django-extra-settings)](https://pepy.tech/project/django-extra-settings)
[![](https://img.shields.io/github/stars/fabiocaccamo/django-extra-settings?logo=github)](https://github.com/fabiocaccamo/django-extra-settings/)
[![](https://img.shields.io/pypi/l/django-extra-settings.svg?color=blue)](https://github.com/fabiocaccamo/django-extra-settings/blob/master/LICENSE.txt)

[![](https://img.shields.io/travis/fabiocaccamo/django-extra-settings?logo=travis&label=build)](https://travis-ci.org/fabiocaccamo/django-extra-settings)
[![](https://img.shields.io/codecov/c/gh/fabiocaccamo/django-extra-settings?logo=codecov)](https://codecov.io/gh/fabiocaccamo/django-extra-settings)
[![](https://img.shields.io/codacy/grade/0dbd5cc2089f4dce80a0e49e6822be3c?logo=codacy)](https://www.codacy.com/app/fabiocaccamo/django-extra-settings)
[![](https://img.shields.io/codeclimate/maintainability/fabiocaccamo/django-extra-settings?logo=code-climate)](https://codeclimate.com/github/fabiocaccamo/django-extra-settings/)
[![](https://requires.io/github/fabiocaccamo/django-extra-settings/requirements.svg?branch=master)](https://requires.io/github/fabiocaccamo/django-extra-settings/requirements/?branch=master)

# django-extra-settings
easily manage typed extra settings using the django admin.
config and manage extra settings using just the django admin.

![](https://user-images.githubusercontent.com/1035294/74425761-81325400-4e54-11ea-9095-3d64e1420bfe.gif)

## Installation
- Run `pip install django-extra-settings`
- Add `extra_settings` to `settings.INSTALLED_APPS`
- Run ``python manage.py migrate``
- Run ``python manage.py collectstatic``
- Restart your application server

## Configuration (optional)

#### Settings
All these settings are optional, if not defined in ``settings.py`` the default values (listed below) will be used.

```python
# if True the template tag will fallback to django.conf.settings,
# very useful to retrieve conf settings such as DEBUG.
EXTRA_SETTINGS_FALLBACK_TO_CONF_SETTINGS = True
```

```python
# the upload_to path value of settings of type 'file'
EXTRA_SETTINGS_FILE_UPLOAD_TO = 'files'
```

```python
# the upload_to path value of settings of type 'image'
EXTRA_SETTINGS_IMAGE_UPLOAD_TO = 'images'
```

## Usage
Just create and edit your extra settings using the admin.

#### Templates
```html
{% load extra_settings %}

{% get_setting 'SETTING_NAME' default='django-extra-settings' %}
```

## Testing
```bash
# create python 3.7 virtual environment
virtualenv testing_django_extra_settings -p "python3.7" --no-site-packages

# activate virtualenv
cd testing_django_extra_settings && . bin/activate

# clone repo
git clone https://github.com/fabiocaccamo/django-extra-settings.git src && cd src

# run tests
python setup.py test
# or
python manage.py test --settings "tests.settings"
```

---

## License
Released under [MIT License](LICENSE.txt).
6 changes: 6 additions & 0 deletions extra_settings/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# -*- coding: utf-8 -*-

from extra_settings import settings


default_app_config = 'extra_settings.apps.ExtraSettingsConfig'
44 changes: 44 additions & 0 deletions extra_settings/admin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# -*- coding: utf-8 -*-

from django.contrib import admin

from extra_settings.forms import SettingForm
from extra_settings.models import Setting


class SettingAdmin(admin.ModelAdmin):

form = SettingForm
value_fields_names = (
'value_bool', 'value_date', 'value_datetime', 'value_decimal',
'value_email', 'value_file', 'value_float', 'value_image',
'value_int', 'value_string', 'value_text', 'value_time', 'value_url',
)
search_fields = ('name', )
list_display = ('name', 'value_type', ) + value_fields_names
list_filter = ('value_type', )
list_editable = value_fields_names
sortable_by = ('name', )

def get_changelist_form(self, request, **kwargs):
return SettingForm

def get_fieldsets(self, request, obj=None):
fields = ('name', 'value_type', )
if obj:
fields += (obj.value_field_name, )
return (
(None, {
'classes': ('wide', ),
'fields': fields,
}),
)

def get_readonly_fields(self, request, obj=None):
return ('value_type', ) if obj else ()

class Media:
css = {'all': ('extra_settings/css/extra_settings.css',), }
js = ['extra_settings/js/extra_settings.js']

admin.site.register(Setting, SettingAdmin)
14 changes: 14 additions & 0 deletions extra_settings/apps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# -*- coding: utf-8 -*-

from django.apps import AppConfig

from extra_settings.translation import gettext_lazy as _


class ExtraSettingsConfig(AppConfig):

name = 'extra_settings'
verbose_name = _('Extra Settings')

def ready(self):
from extra_settings import signals
25 changes: 25 additions & 0 deletions extra_settings/cache.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# -*- coding: utf-8 -*-

from django.conf import settings
from django.core.cache import cache, caches


def _get_cache():
return caches['extra_settings'] \
if 'extra_settings' in settings.CACHES else cache


def _get_cache_key(key):
return 'extra_settings_{}'.format(key)


def del_cached_setting(key):
_get_cache().delete(_get_cache_key(key))


def get_cached_setting(key):
return _get_cache().get(_get_cache_key(key), None)


def set_cached_setting(key, value):
_get_cache().set(_get_cache_key(key), value)
28 changes: 28 additions & 0 deletions extra_settings/forms.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# -*- coding: utf-8 -*-

from django import forms
from django.conf import settings

from extra_settings.models import Setting


class SettingForm(forms.ModelForm):

class Meta:
model = Setting
fields = '__all__'

def __init__(self, *args, **kwargs):
super(SettingForm, self).__init__(*args, **kwargs)
# resize text area
if 'value_text' in self.fields:
self.fields['value_text'].widget = forms.Textarea(
attrs={'rows': 5, 'cols': 51})

def clean_name(self):
value = self.cleaned_data.get('name', '')
if hasattr(settings, value):
raise forms.ValidationError(
'Invalid setting name, settings.{} already '
'defined in django.conf.settings.'.format(value))
return value
41 changes: 41 additions & 0 deletions extra_settings/migrations/0001_initial.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Generated by Django 3.0.3 on 2020-02-12 12:33

from decimal import Decimal
from django.db import migrations, models


class Migration(migrations.Migration):

initial = True

dependencies = [
]

operations = [
migrations.CreateModel(
name='Setting',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(help_text='(e.g. SETTING_NAME)', max_length=50, unique=True, verbose_name='Name')),
('value_type', models.CharField(choices=[('bool', 'bool'), ('date', 'date'), ('datetime', 'datetime'), ('decimal', 'decimal'), ('email', 'email'), ('file', 'file'), ('float', 'float'), ('image', 'image'), ('int', 'int'), ('string', 'string'), ('text', 'text'), ('time', 'time'), ('url', 'url')], max_length=20, verbose_name='Type')),
('value_bool', models.BooleanField(default=False, verbose_name='Value')),
('value_date', models.DateField(blank=True, null=True, verbose_name='Value')),
('value_datetime', models.DateTimeField(blank=True, null=True, verbose_name='Value')),
('value_decimal', models.DecimalField(blank=True, decimal_places=10, default=Decimal('0.0'), max_digits=19, verbose_name='Value')),
('value_email', models.EmailField(blank=True, max_length=254, verbose_name='Value')),
('value_file', models.FileField(blank=True, upload_to='files', verbose_name='Value')),
('value_float', models.FloatField(blank=True, default=0.0, verbose_name='Value')),
('value_image', models.FileField(blank=True, upload_to='images', verbose_name='Value')),
('value_int', models.IntegerField(blank=True, default=0, verbose_name='Value')),
('value_string', models.CharField(blank=True, max_length=50, verbose_name='Value')),
('value_text', models.TextField(blank=True, verbose_name='Value')),
('value_time', models.TimeField(blank=True, null=True, verbose_name='Value')),
('value_url', models.URLField(blank=True, verbose_name='Value')),
],
options={
'verbose_name': 'Setting',
'verbose_name_plural': 'Settings',
'ordering': ['name'],
},
),
]
Empty file.
Loading

0 comments on commit d920aed

Please sign in to comment.