Giter Site home page Giter Site logo

zlorf / django-dbsettings Goto Github PK

View Code? Open in Web Editor NEW

This project forked from hdg700/django-dbsettings

64.0 7.0 38.0 287 KB

Application settings whose values can be updated while a project is up and running

License: BSD 3-Clause "New" or "Revised" License

Python 92.78% HTML 7.22%

django-dbsettings's People

Contributors

a1tus avatar alfredo avatar aminhp avatar andybak avatar danielroseman avatar djm avatar elidickinson avatar gulopine avatar hdg700 avatar j0nm1 avatar johnpaulett avatar konratt avatar lexich avatar mlier avatar natureshadow avatar nerdoc avatar paulogiacomelli avatar sciyoshi avatar sergey-zakharov avatar steinerkelvin avatar suvit avatar tigorc avatar wkleinheerenbrink avatar zlorf avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

django-dbsettings's Issues

hashlib.md5 problems in Python 3.5 with ImageValue

Hello,

The fix applied for Issue #28 is raising a new error on Python 3.5:

hashed_name = md5(six.binary_type(time.time())).hexdigest() + value.name[-4:]
TypeError: 'float' object is not iterable

Current Line 309:

        hashed_name = md5(six.binary_type(time.time())).hexdigest() + value.name[-4:]

SOLUTION

Please go back using function six.text_type() and encode the result so it is compatible with Python 3.0+.

Line 309 must be like this:

        hashed_name = md5(six.text_type(time.time()).encode()).hexdigest() + value.name[-4:]

It was tested on Python 2.7 and Python 3.5 and works great!

Regards.

Better document usage

Hello! I have some bits of config that can change by environment but are not secrets, and need to be editable without code changes and deployment. On a previous project, we had a custom model (with a small number of fields for our config buts) linked to sites.Site that did the job well. I thought dbsettings could be an easier and more powerful way (thanks to the included types) to do this, but it seems like I’m misunderstanding something in the docs.

After defining a class (with two settings without default values) and running migrations, I don’t see anything in the edit view. Is it mandatory to reference the settings from another model? Or is there some code I’m missing to make my settings appear in the admin?

Creating an 'official' project fork?

Hi, I'm using your fork as it seemed to be the most active and stable.

Would you be interested in making it the 'official' version? Here's what I propose:

  1. Create a Github group called django-dbsettings so the project url would be: https://github.com/django-dbsettings/django-dbsettings. You would obvious be the main member but you could invite anyone else with an active fork to join if you preferred to share the burden
  2. Asking sciyoshi to update his README to point at the new project and also assign you as the manager on PyPi

I've done this recently with django-backup and django-admin-tools. I think it's the best way forward when the primary repo for a project is no longer being updated.

Alternatively - you can skip the Github group part if you prefer. I just think it's a nicer long-term strategy - if you cease to be interested in being the primary maintainer then it's much easier to pass the mantel.

Can't syncdb

Using python-2.7 and Django-1.7 and django-dbsettings-0.7

I have created options.py in my app with next content

import dbsettings

class GeneralOptions(dbsettings.Group):
    network = dbsettings.StringValue(
        'management network',
        default='192.168.200.0/24',
        help_text='Management network (where cluster nodes live)')


general = GeneralOptions('GeneralOptions')

Then I import whole module in my app's models.py, but when I do ./manage.py syncdb I get error

CommandError: System check identified some issues:

ERRORS:
dbsettings.Setting.site: (fields.E300) Field defines a relation with model 'Site', which is either not installed, or is abstract.

What I do wrong?

ForeignKey warning with Django 1.10

System check identified no issues (0 silenced).
venv/lib/python3.5/site-packages/dbsettings/migrations/0001_initial.py:24:

RemovedInDjango20Warning: on_delete will be a required arg for ForeignKey in Django 2.0. Set it to models.CASCADE on models and in existing migrations if you want to maintain the current default behavior.
See https://docs.djangoproject.com/en/1.10/ref/models/fields/#django.db.models.ForeignKey.on_delete

] + ([('site', models.ForeignKey(to='sites.Site'))] if USE_SITES else [])

using choices returns TypeError

I am trying to set the choices for a StringValue using the tuple of tuples as specified in django docs and am getting the error

TypeError: The type of CHOICES (tuple) is not a valid Value.

when doing a simple

CHOICES = (
        ('A', 'Thing A'),
        ('B', 'Thing B'),
    )

    test = dbsettings.StringValue(default='A', 
        choices=CHOICES)

migrate or syncdb warning on dbsettings 0.9.3 and django 1.8.5?

On Django 1.8.5 and dbsettings 0.9.3, I can't create the fields.

For testing purposes I used this on my core.models.py

import dbsettings

class EmailOptions(dbsettings.Group):
    enabled = dbsettings.BooleanValue('whether to send emails or not')
    sender = dbsettings.StringValue('address to send emails from')
    subject = dbsettings.StringValue(default='SiteMail')

email = EmailOptions()       

After migrate, the table exists in the database but the values are never populated.
If I try to run migrate again or syncdb it raises an error:

The following content types are stale and need to be deleted:

    core | 

Any objects related to these content types by a foreign key will also
be deleted. Are you sure you want to delete these content types?
If you're unsure, answer 'no'.

    Type 'yes' to continue, or 'no' to cancel: 

Either yes or no does nothing.

# select * from dbsettings_setting;
 id | module_name | class_name | attribute_name | value 
----+-------------+------------+----------------+-------
(0 rows)

Does anyone with django 1.8.5 have the save issue?

non-required integer value raises error

Hi,

I have a dbsettings.PositiveIntegerValue(required=False)

In the settings edition page, it is impossible to save changes if the above setting is left untouched. It raises: int() argument must be a string or a number, not 'NoneType'

Is this a bug or am I missing something?

Thanks!

Emit signal on settings change in group instance

It would be good if changing settings would emit a signal that can be used to react to settings changes.

In practice, I am defining settings for a Bootstrap colour theme, and want to regenerate stylesheets from SCSS after the settings have been changed. I am listening to the post_save signal of the Setting model now, which is inefficient.

DBSETTINGS_VALUE_LENGTH and migrations

In #17 I suggested using a TextField instead of a CharField for the settings field as the 255 char limit was a major limitation for many use cases.

You suggested instead adding a setting DBSETTINGS_VALUE_LENGTH to allow overriding of max_length.

I've just switched back to using this branch instead of my own fork and I spotted the fact that you use this setting inside the initial migration. Therefore this setting gets 'baked in' to the schema on the first migration. Changing is after that is a bit tricky - anyone doing so would have to set their own MIGRATION_MODULES setting: https://docs.djangoproject.com/en/1.8/ref/settings/#std:setting-MIGRATION_MODULES and become responsible for managing any future migrations.

At the very least this should be documented. People should choose a high-enough DBSETTINGS_VALUE_LENGTH before their first migration to reduce the likelihood of needing a custom MIGRATION_MODULES setting.

Choice settings?

Hi,

Many of the settings in my current application (which does not use db settings yet!) are choices, eg:

FOO_CHOICES = (
    (u'OK', 'Approved'),
    (u'FAIL', 'Rejected'),
)

I don't see any choice-like setting in the value types. I understand that this might be because there is no obvious mapping to primitive values to put in the database.

The most crazy solution I can think of is to use a String setting with the content "((u'OK', 'Approved'), (u'FAIL', 'Rejected'),)" and then use eval to get the dictionary back. This is of course a bit violent and risky.

What would you recommend?

Thanks!

MultipleObjectsReturned at /settings/

There seems to be a huge issue, the settings view is making objects over and over instead of modifying the existing Settings models.

Then at this point in loading.py I get the multiple objects error.

storage = Setting.objects.get(
                module_name=module_name,
                class_name=class_name,
                            attribute_name=attribute_name, ...
            )

I haven't been able to directly find the place where the Settings objects are created, so I have no idea why its making the same object twice.

Invalid ContentType after running "migrate" command

When using django 1.7 migrations i get the following message:

> ./manage migrate
...
The following content types are stale and need to be deleted:
    core |

core - is my app where i use django-dbsettings.

I found this closed ticket in django bugtracker: https://code.djangoproject.com/ticket/23519
Here is code which creates content-type with empty model: https://github.com/zlorf/django-dbsettings/blob/master/dbsettings/management.py#L13

    ct, created = ContentType.objects.get_or_create(model='', app_label=appname,
                                                    defaults={'name': appname})

To fix this we need to tell django "we need this model, so don't touch this" or find another way to implement app-level permissions.

ForeignKey value

I was wondering whether it wouldn't be possible to have a setting holding a foreign key, or a reference to some model.

The use case is that I have a model defining a collection of objects, of which a single one can be active in the application at any time. I need to switch there in a setting.

WIlling to propose a PR if the maintainer doesn't object to it by design.

empty settings page after port

Hi,

I've been using dbsettings for quite some time, without any issue.

Recently we migrated our django app from python2/django1.11/suit to python3/django2.2/baton, and as an unexpected consequence, the dbsettings page is empty (pg is the name of the app):

Screen Shot 2020-06-22 at 3 49 47 AM

Apart from that, everything is functional. The dbsettings are accessible programmatically, and appropriately set, etc. It's really just the web interface to the dbsettings that is not working.

Any idea on what could be happening here??

Thanks!

App level settings not showing up anywhere.

  1. I installed the package into my environment
    pip install django-dbsettings
  2. I installed it into my settings
    `INSTALLED_APPS = [ ..., 'dbsettings']
  3. I configured the urlpattern for it
    path('admin/settings/', include('dbsettings.urls')), and tried path('settings/', include('dbsettings.urls')),
  4. In my models for my base app I have
# base/models.py

import dbsettings
...

class SiteSettings(dbsettings.Group):
    company_name = dbsettings.StringValue(default='Your Company Name')

site_settings = SiteSettings()

class MyModel(models.Model): 
    name = models.CharField(default='blah')

    def __str__(self):
        return self.name
  1. I did python manage.py migrate and the settings model registered.

And when I go to 127.0.0.1:8000/admin/settings/ or 127.0.0.1:8000/settings/, it just says the app name Base with the button Save with no items or settings to select.
image

Did I do something wrong?

If so (or not), can you please make it clearer in the instructions how to set app level settings?

Extra files in PyPI archive

There are some unnecessary items in the package published on PyPI. Namely, an app and a cbv package:

$ tar tf django-dbsettings-0.7.tar.gz | sort
django-dbsettings-0.7/
django-dbsettings-0.7/app/
django-dbsettings-0.7/app/admin.py
django-dbsettings-0.7/app/__init__.py
django-dbsettings-0.7/app/models.py
django-dbsettings-0.7/AUTHORS
django-dbsettings-0.7/cbv/
django-dbsettings-0.7/cbv/__init__.py
django-dbsettings-0.7/cbv/settings.py
django-dbsettings-0.7/cbv/urls.py
django-dbsettings-0.7/cbv/wsgi.py
django-dbsettings-0.7/dbsettings/
django-dbsettings-0.7/dbsettings/forms.py
django-dbsettings-0.7/dbsettings/group.py
django-dbsettings-0.7/dbsettings/__init__.py
django-dbsettings-0.7/dbsettings/loading.py
django-dbsettings-0.7/dbsettings/locale/
django-dbsettings-0.7/dbsettings/locale/pl/
django-dbsettings-0.7/dbsettings/locale/pl/LC_MESSAGES/
django-dbsettings-0.7/dbsettings/locale/pl/LC_MESSAGES/django.mo
django-dbsettings-0.7/dbsettings/locale/pl/LC_MESSAGES/django.po
django-dbsettings-0.7/dbsettings/management.py
django-dbsettings-0.7/dbsettings/models.py
django-dbsettings-0.7/dbsettings/templates/
django-dbsettings-0.7/dbsettings/templates/dbsettings/
django-dbsettings-0.7/dbsettings/templates/dbsettings/app_settings.html
django-dbsettings-0.7/dbsettings/templates/dbsettings/site_settings.html
django-dbsettings-0.7/dbsettings/templates/dbsettings/values.html
django-dbsettings-0.7/dbsettings/tests/
django-dbsettings-0.7/dbsettings/tests/__init__.py
django-dbsettings-0.7/dbsettings/tests/tests.py
django-dbsettings-0.7/dbsettings/tests/test_urls.py
django-dbsettings-0.7/dbsettings/urls.py
django-dbsettings-0.7/dbsettings/utils.py
django-dbsettings-0.7/dbsettings/values.py
django-dbsettings-0.7/dbsettings/views.py
django-dbsettings-0.7/django_dbsettings.egg-info/
django-dbsettings-0.7/django_dbsettings.egg-info/dependency_links.txt
django-dbsettings-0.7/django_dbsettings.egg-info/PKG-INFO
django-dbsettings-0.7/django_dbsettings.egg-info/SOURCES.txt
django-dbsettings-0.7/django_dbsettings.egg-info/top_level.txt
django-dbsettings-0.7/LICENSE
django-dbsettings-0.7/MANIFEST.in
django-dbsettings-0.7/PKG-INFO
django-dbsettings-0.7/README.rst
django-dbsettings-0.7/runtests.py
django-dbsettings-0.7/setup.cfg
django-dbsettings-0.7/setup.py

These get installed to site-packages when using python setup.py install.

Too many titles

I don't want/need to group my settings (flat is better than nested ;-) ) so I've only got a single group. Unfortunately the settings page in the admin has a heck of a lot of titles that I can't get rid of

  1. Site settings (the global h1)
  2. "DJANGO_SITE" (my app_label)
  3. "Application settings" (hard-coded)

If I set verbose_name on the group it adds another title underneath 'Application settings' rather than replacing it as I would have expected.

So - bare minimum the page has 3 titles. Ideally I'd like one - the h1 is sufficient. I can understand the app_label as a subtitle if I had more than one app_label but even in this case shouldn't it be optional?

Increasing max_length of 'value' field

I'm using dbsettings to allow editing of HTML snippets that aren't specific to a particular page on the site.

A max_length of 255 is too short in many cases. I'm pondering the best way to handle this:

  1. Increase it for everyone. Is there a problem with this? As far as I'm aware - varchar fields only use the amount of storage they need but there is probably some performance or storage cost. My hunch is that it's negligible.
  2. Make the base Setting class abstract or swappable so users can tweak this. Seems a bit complicated unless there are other benefits you can see growing from this.
  3. Stick to what we've got and I'll fork it. Obviously my least favourite option as I'll need to track changes forever more. However - if you feel that it's especially weird of me to want values longer than 255 then I can see this option might be your preferred one.

django-dbsettings prevents django.contrib.sites from being installed.

The error:

django.db.migrations.exceptions.InconsistentMigrationHistory: Migration dbsettings.0001_initial is applied before its dependency sites.0001_initial on database 'default'.

Instead of making sites mandatory, there is a migration that adapts itself to the app. Now I have to use a custom MIGRATIONS_MODULES setting with a sanitized migration in order to bypass this. I think that it would have been more consistent to make django.contrib.sites mandatory.

settings as models in admin panel view

1st question is, pip installing 1 or 2?

  1. https://github.com/zlorf/django-dbsettings/
  2. https://github.com/saxix/django-dbsettings/

2nd question is about possiblity to present options as standard table template as models in admin panel view (as separated models or agregated in model but as 2 tables in concept of
options = Options1("options 1") + options = Options2("options 2") where Options1 is first table and Options2 second table.
Why this? Well.. if we have many vars then need filter to search this eq. by true/false, not ctr+f thats if horrible, and select all functions to change true/false is nice. Adding vars in table look nice, filtering, etc, and logs about changes.
Soo.. maybe django-dbsettings-2 is need? Any comment in this way?

ImageValue: hashlib.md5 problems with Python 3.x

Hello,

I'm using Python 3.5 and Dango 1.9.

When I use ImageValue i'm getting the following error:

File "/home/user/virtualenv3.5/lib/python3.5/site-packages/dbsettings/values.py", line 306, in get_db_prep_save
    hashed_name = md5(six.text_type(time.time())).hexdigest() + value.name[-4:]
TypeError: Unicode-objects must be encoded before hashing

So you can see that the problem is on file dbsettings/values.py on line 306:

hashed_name = md5(six.text_type(time.time())).hexdigest() + value.name[-4:]

CAUSE

Since Python 3.0, for hashlib.md5 you need to pass bytes instead of str. You can confirm that in Python documentation:

https://docs.python.org/2.7/library/hashlib.html
https://docs.python.org/3.0/library/hashlib.html
https://docs.python.org/3.1/library/hashlib.html
...
https://docs.python.org/3.5/library/hashlib.html

RESOLUTION

Replace line 306 with the following code:

        import sys
        PYTHON_VERSION = sys.version_info
        value_to_hash = six.text_type(time.time())
        if PYTHON_VERSION >= (3, 0):
            value_to_hash = value_to_hash.encode()
        hashed_name = md5(value_to_hash).hexdigest() + value.name[-4:]

Thanks for your great work.

settings/ - superuser does not have permissions to edit

Django version 3.2.5
Logged in to admin as Superuser but seeing this message when accessing from localhost:8000/settings/

"You don't have permission to edit values."

I can visit admin and am logged in.
If I comment the staff-required decorator in views.py the issue remains

Migrations not included in PyPI download

Maybe I'm missing something obvious, but I can see the 0001_initial migration in the repo, but that directory appears to be missing from the tar.gz on PyPI

$ wget https://pypi.python.org/packages/source/d/django-dbsettings/django-dbsettings-0.8.1.tar.gz
$ tar -ztvf django-dbsettings-0.8.1.tar.gz | grep -c migrations
0

Is there some packaging issue? Thanks!

Remove previous image file when ImageValue change

Hi,

When the value of an ImageValue field changes, the previous image file is preserved in the file system.

It would be a good improvement to remove the previous file just after the new one is uploaded.

To do this I inserted the following code in line 320 of value.py:

        # Remove previous image file:
        current_value = self.__get__(value)
        current_filename = pjoin(settings.MEDIA_ROOT, current_value)
        if os.path.isfile(current_filename):
            os.remove(current_filename)

As a reference, the complete get_db_prep_save() function must look like this:

    def get_db_prep_save(self, value):
        "Returns a value suitable for storage into a CharField"
        if not value:
            return None

        hashed_name = md5(six.text_type(time.time()).encode()).hexdigest() + value.name[-4:]
        image_path = pjoin(self._upload_to, hashed_name)
        dest_name = pjoin(settings.MEDIA_ROOT, image_path)
        directory = pjoin(settings.MEDIA_ROOT, self._upload_to)

        if not os.path.exists(directory):
            os.makedirs(directory)
        with open(dest_name, 'wb+') as dest_file:
            for chunk in value.chunks():
                dest_file.write(chunk)

        # Remove previous image file:
        current_value = self.__get__(value)
        current_filename = pjoin(settings.MEDIA_ROOT, current_value)
        if os.path.isfile(current_filename):
            os.remove(current_filename)

        return six.text_type(image_path)

I tested this on Django 1.9 With Python 3.5 and as you can see the code will work on any version of Python.

Django version compatibility?

The PyPI page and the README don't mention which Django versions the latest release of django-dbsettings is compatible with.

Release new version on PyPI

Hi,
could you please release a new version on PyPI? The last version is 1.2.0 which is not compatible with Django 4.0. The changes to make it compatible are already on the master branch but sadly there is no version with them on PyPI.

Django 3.0 support aka Drop Python 2 support

Django 3.0 removes the django.utils.six module and advises to move to the standard six library.

With Python 2 being end of life, I'd instead suggest dropping Python 2 compatibility altogether.

dbsettings forcing to use sites framework

I'm using Python 3.5 and Django 1.9.

I just created test project, added 'dbsettings' in INSTALLED_APPS on settings.py and ran the dev server with python manage.py runserver.

I'm getting the following error:

  File "/home/user/virtualenv3.5/lib/python3.5/site-packages/dbsettings/models.py", line 2, in <module>
    from django.contrib.sites.models import Site
  File "/home/user/virtualenv3.5/lib/python3.5/site-packages/django/contrib/sites/models.py", line 83, in <module>
    class Site(models.Model):
  File "/home/user/virtualenv3.5/lib/python3.5/site-packages/django/db/models/base.py", line 103, in __new__
    "application was loaded. " % (module, name))
RuntimeError: Model class django.contrib.sites.models.Site doesn't declare an explicit app_label and either isn't in an application in INSTALLED_APPS or else was imported before its application was loaded. 

But, if I add 'django.contrib.sites' in INSTALLED_APPS everything works OK.

The issue is that I do not need sites framework. I tried setting the variable DBSETTINGS_USE_SITES = False in settings.py and it did not help (the same error message).

I checked the source code of the file dbsettings/models.py and I believe I detected the problem: django.contrib.sites.models.Site must be imported only if using sites framework (USE_SITES). So the file dbsettings/models.py must be updated like this:

from django.db import models
from dbsettings.settings import USE_SITES, VALUE_LENGTH

if USE_SITES:
    from django.contrib.sites.models import Site

    class SiteSettingManager(models.Manager):
        def get_queryset(self):
            sup = super(SiteSettingManager, self)
            qs = sup.get_queryset() if hasattr(sup, 'get_queryset') else sup.get_query_set()
            return qs.filter(site=Site.objects.get_current())
        get_query_set = get_queryset


class Setting(models.Model):
    module_name = models.CharField(max_length=255)
    class_name = models.CharField(max_length=255, blank=True)
    attribute_name = models.CharField(max_length=255)
    value = models.CharField(max_length=VALUE_LENGTH, blank=True)

    if USE_SITES:
        site = models.ForeignKey(Site)
        objects = SiteSettingManager()

        def save(self, *args, **kwargs):
            self.site = Site.objects.get_current()
            return super(Setting, self).save(*args, **kwargs)

    def __bool__(self):
        return self.pk is not None

Please confirm if this change is valid and apply it to the repo.

Thanks for your work.

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.