diff --git a/inventory/admin/__init__.py b/inventory/admin/__init__.py index 5635118..2f7da51 100644 --- a/inventory/admin/__init__.py +++ b/inventory/admin/__init__.py @@ -1 +1,2 @@ from inventory.admin.item import ItemModelAdmin # noqa +from inventory.admin.location import LocationModelAdmin # noqa diff --git a/inventory/admin/base.py b/inventory/admin/base.py new file mode 100644 index 0000000..8f86bef --- /dev/null +++ b/inventory/admin/base.py @@ -0,0 +1,9 @@ +from reversion_compare.admin import CompareVersionAdmin + + +class BaseUserAdmin(CompareVersionAdmin): + def save_model(self, request, obj, form, change): + if obj.user_id is None: + obj.user = request.user + + super().save_model(request, obj, form, change) diff --git a/inventory/admin/item.py b/inventory/admin/item.py index b15d1e2..eb862c2 100644 --- a/inventory/admin/item.py +++ b/inventory/admin/item.py @@ -1,9 +1,9 @@ from django.contrib import admin -from reversion_compare.admin import CompareVersionAdmin +from inventory.admin.base import BaseUserAdmin from inventory.models import ItemModel @admin.register(ItemModel) -class ItemModelAdmin(CompareVersionAdmin): +class ItemModelAdmin(BaseUserAdmin): pass diff --git a/inventory/admin/location.py b/inventory/admin/location.py new file mode 100644 index 0000000..f652387 --- /dev/null +++ b/inventory/admin/location.py @@ -0,0 +1,9 @@ +from django.contrib import admin + +from inventory.admin.base import BaseUserAdmin +from inventory.models import LocationModel + + +@admin.register(LocationModel) +class LocationModelAdmin(BaseUserAdmin): + pass diff --git a/inventory/models/__init__.py b/inventory/models/__init__.py index 88ee3ef..e46d5a9 100644 --- a/inventory/models/__init__.py +++ b/inventory/models/__init__.py @@ -1 +1,2 @@ from inventory.models.item import ItemModel # noqa +from inventory.models.location import LocationModel # noqa diff --git a/inventory/models/base.py b/inventory/models/base.py index d13193f..d2c107e 100644 --- a/inventory/models/base.py +++ b/inventory/models/base.py @@ -1,8 +1,10 @@ import uuid from bx_py_utils.models.timetracking import TimetrackingBaseModel +from django.conf import settings from django.db import models from django.utils.translation import ugettext_lazy as _ +from tagulous.models import TagField class BaseModel(TimetrackingBaseModel): @@ -10,7 +12,28 @@ class BaseModel(TimetrackingBaseModel): primary_key=True, default=uuid.uuid4, editable=False, - verbose_name=_('ID') + verbose_name=_('BaseModel.id.verbose_name'), + help_text=_('BaseModel.id.help_text') + ) + user = models.ForeignKey( # "Owner" of this entry + settings.AUTH_USER_MODEL, + related_name='+', + on_delete=models.CASCADE, + editable=False, # Must be set automatically and never changed + verbose_name=_('BaseModel.user.verbose_name'), + help_text=_('BaseModel.user.help_text') + ) + name = models.CharField( + max_length=255, + verbose_name=_('BaseModel.name.verbose_name'), + help_text=_('BaseModel.name.help_text') + ) + tags = TagField( + blank=True, + force_lowercase=True, + max_count=10, + verbose_name=_('BaseModel.tags.verbose_name'), + help_text=_('BaseModel.tags.help_text') ) class Meta: diff --git a/inventory/models/item.py b/inventory/models/item.py index 80441d1..fef135f 100644 --- a/inventory/models/item.py +++ b/inventory/models/item.py @@ -10,11 +10,29 @@ class ItemModel(BaseModel): A Item that can be described and store somewhere ;) """ description = RichTextUploadingField( - config_name='ItemModel.description' + config_name='ItemModel.description', + verbose_name=_('ItemModel.description.verbose_name'), + help_text=_('ItemModel.description.help_text') ) fcc_id = models.CharField( max_length=20, blank=True, null=True, - verbose_name='FCC ID', - help_text=_('FCC ID-Number for links to: https://fccid.io/') + verbose_name=_('ItemModel.fcc_id.verbose_name'), + help_text=_('ItemModel.fcc_id.help_text') ) + location = models.ForeignKey( + 'inventory.LocationModel', + blank=True, null=True, on_delete=models.SET_NULL, + verbose_name=_('ItemModel.location.verbose_name'), + help_text=_('ItemModel.location.help_text') + ) + + def __str__(self): + if self.location_id is None: + return self.name + else: + return f'{self.name} ({self.location})' + + class Meta: + verbose_name = _('ItemModel.verbose_name') + verbose_name_plural = _('ItemModel.verbose_name_plural') diff --git a/inventory/models/location.py b/inventory/models/location.py index e69de29..a1f0821 100644 --- a/inventory/models/location.py +++ b/inventory/models/location.py @@ -0,0 +1,33 @@ +from ckeditor_uploader.fields import RichTextUploadingField +from django.db import models +from django.utils.translation import ugettext_lazy as _ + +from inventory.models.base import BaseModel + + +class LocationModel(BaseModel): + """ + A Storage for items. + """ + description = RichTextUploadingField( + config_name='LocationModel.description', + verbose_name=_('LocationModel.description.verbose_name'), + help_text=_('LocationModel.description.help_text') + ) + parent = models.ForeignKey( + 'self', + on_delete=models.SET_NULL, + blank=True, null=True, + verbose_name=_('LocationModel.parent.verbose_name'), + help_text=_('LocationModel.parent.help_text') + ) + + def __str__(self): + if self.parent_id is None: + return self.name + else: + return f'{self.name} -> {self.parent}' + + class Meta: + verbose_name = _('LocationModel.verbose_name') + verbose_name_plural = _('LocationModel.verbose_name_plural') diff --git a/inventory_project/settings.py b/inventory_project/settings.py index cd3873f..882d1fc 100644 --- a/inventory_project/settings.py +++ b/inventory_project/settings.py @@ -44,6 +44,7 @@ INSTALLED_APPS = ( 'ckeditor', # https://github.com/django-ckeditor/django-ckeditor 'reversion', # https://github.com/etianen/django-reversion 'reversion_compare', # https://github.com/jedie/django-reversion-compare + 'tagulous', # https://github.com/radiac/django-tagulous 'inventory.apps.InventoryConfig', ) @@ -109,7 +110,9 @@ LANGUAGES = [ ('de', _('German')), ('en', _('English')), ] - +LOCALE_PATHS = [ + __Path(BASE_PATH, 'locale') +] USE_I18N = True USE_L10N = True TIME_ZONE = 'Europe/Paris' @@ -117,6 +120,7 @@ USE_TZ = True # _____________________________________________________________________________ # Static files (CSS, JavaScript, Images) + STATIC_URL = '/static/' STATIC_ROOT = str(__Path(BASE_PATH, 'static')) @@ -142,33 +146,20 @@ CKEDITOR_BASEPATH = STATIC_URL + 'ckeditor/ckeditor/' CKEDITOR_UPLOAD_PATH = 'uploads/' CKEDITOR_FILENAME_GENERATOR = 'utils.get_filename' CKEDITOR_CONFIGS = { - # 'ItemModel.description': { - # 'toolbar': 'full', - # 'height': '25em', - # 'width': '100%', - # 'removeButtons': 'Language,Flash,iframes,bidiltr' - # }, 'ItemModel.description': { 'skin': 'moono-lisa', - # 'toolbar_Basic': [['Source', '-', 'Bold', 'Italic']], - # 'toolbar_Full': [ - # [ - # 'Styles', - # 'Format', - # 'Bold', - # 'Italic', - # 'Underline', - # 'Strike', - # 'SpellChecker', - # 'Undo', - # 'Redo', - # ], - # ['Link', 'Unlink', 'Anchor'], - # ['Image', 'Flash', 'Table', 'HorizontalRule'], - # ['TextColor', 'BGColor'], - # ['Smiley', 'SpecialChar'], - # ['Source'], - # ], + 'removeButtons': 'Language', + + # plugins are here: site-packages/ckeditor/static/ckeditor/ckeditor/plugins + 'removePlugins': 'wsc,div,flash,iframe,bidi', + 'toolbar': 'full', + 'height': '25em', + 'width': '100%', + 'filebrowserWindowWidth': 940, + 'filebrowserWindowHeight': 725, + }, + 'LocationModel.description': { + 'skin': 'moono-lisa', 'removeButtons': 'Language', # plugins are here: site-packages/ckeditor/static/ckeditor/ckeditor/plugins @@ -181,6 +172,15 @@ CKEDITOR_CONFIGS = { } } +# _____________________________________________________________________________ +# http://radiac.net/projects/django-tagulous/documentation/installation/#settings + +TAGULOUS_NAME_MAX_LENGTH = 255 +TAGULOUS_SLUG_MAX_LENGTH = 50 +TAGULOUS_LABEL_MAX_LENGTH = TAGULOUS_NAME_MAX_LENGTH +TAGULOUS_SLUG_TRUNCATE_UNIQUE = 5 +TAGULOUS_SLUG_ALLOW_UNICODE = False + # _____________________________________________________________________________ # cut 'pathname' in log output diff --git a/poetry.lock b/poetry.lock index 6988204..990507d 100644 --- a/poetry.lock +++ b/poetry.lock @@ -272,6 +272,22 @@ diff-match-patch = "*" django = ">=2.2,<3.1" django-reversion = "*" +[[package]] +name = "django-tagulous" +version = "1.0.0" +description = "Fabulous Tagging for Django" +category = "main" +optional = false +python-versions = "*" + +[package.dependencies] +Django = ">=1.11" + +[package.extras] +dev = ["tox", "jasmine"] +devdb = ["psycopg2", "mysqlclient"] +i18n = ["unidecode"] + [[package]] name = "django-tools" version = "0.46.1" @@ -952,7 +968,7 @@ testing = ["pytest (>=3.5,<3.7.3 || >3.7.3)", "pytest-checkdocs (>=1.2.3)", "pyt [metadata] lock-version = "1.1" python-versions = ">=3.7,<4.0.0" -content-hash = "464ca363f2392ed7c45d131f91148bd1cffb4536f5f88c390d502054d06e95ea" +content-hash = "81bfc3b102483db10838f298a425e9436883c93f06940662e7e7b85b4b9d8308" [metadata.files] appdirs = [ @@ -1139,6 +1155,9 @@ django-reversion-compare = [ {file = "django-reversion-compare-0.12.2.tar.gz", hash = "sha256:9ec6c764a2bcb2be52fa1b4ef4365f8226a89c7b572ab984afe24b76d6247b5f"}, {file = "django_reversion_compare-0.12.2-py3-none-any.whl", hash = "sha256:5ce8d402add477a3c38aae8335af22b3abdfffa83ef5333c06c865abb89e9cbd"}, ] +django-tagulous = [ + {file = "django-tagulous-1.0.0.tar.gz", hash = "sha256:9b4fa1773845a1cf33d21b27f9cdafc6f3fe29a480428bdd8f8717e7d4742396"}, +] django-tools = [ {file = "django-tools-0.46.1.tar.gz", hash = "sha256:0a289c230d908417a0a72d1a7884ebc0508894b1ac7be888ed333170d4c97291"}, {file = "django_tools-0.46.1-py3-none-any.whl", hash = "sha256:e10c13b382b14ecfb589fd194719d44210a26a542869cbb298e0c2a1ede7f90d"}, diff --git a/pyproject.toml b/pyproject.toml index 34831e3..11a1c61 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -49,6 +49,7 @@ django-tools = "*" # https://github.com/jedie/django-tools/ django-reversion-compare = "*" # https://github.com/jedie/django-reversion-compare/ django-ckeditor = "*" # https://github.com/django-ckeditor/django-ckeditor bx_py_utils = "*" # https://github.com/boxine/bx_py_utils +django-tagulous = "*" # https://github.com/radiac/django-tagulous [tool.poetry.dev-dependencies] poetry-publish = "*" # https://github.com/jedie/poetry-publish