{ "info": { "author": "vb YAZILIM", "author_email": "hello@vbyazilim.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 4 - Beta", "Environment :: Web Environment", "Framework :: Django", "Framework :: Django :: 2.2", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3 :: Only", "Topic :: Internet :: WWW/HTTP", "Topic :: Internet :: WWW/HTTP :: Dynamic Content" ], "description": "![Python](https://img.shields.io/badge/python-3.7.4-green.svg)\n![Django](https://img.shields.io/badge/django-2.2.6-green.svg)\n![Version](https://img.shields.io/badge/version-1.0.2-orange.svg)\n[![Codacy Badge](https://api.codacy.com/project/badge/Grade/4c6aa76f09fd437eb3888855fccc9604)](https://www.codacy.com/manual/vigo/django-vb-baseapp?utm_source=github.com&utm_medium=referral&utm_content=vbyazilim/django-vb-baseapp&utm_campaign=Badge_Grade)\n\n# django-vb-baseapp\n\nThis is a helper app for https://github.com/vbyazilim/django-vb-admin\nBefore you use this, you need to install `django-vb-admin`:\n\n```bash\n$ pip install django-vb-admin\n```\n\n## Features\n\n- 2 custom base models: `BaseModel` and `BaseModelWithSoftDelete`\n- 2 custom base model admins: `CustomBaseModelAdmin` and `CustomBaseModelAdminWithSoftDelete`\n- Soft deletion feature for model and model admin and admin actions\n- `pre_undelete` and `post_undelete` signals for soft delete operation\n- Pre enabled models admin site: `ContentTypeAdmin`, `LogEntryAdmin`, `PermissionAdmin`, `UserAdmin`\n- Timezone and locale middlewares\n- View level on screen debug feature\n- Handy utils: `numerify`, `save_file`, `SlackExceptionHandler`\n- File widget for Django Admin: `AdminImageFileWidget`\n- `OverwriteStorage` for overwriting file uploads\n- Custom file storage for missing files for development environment: `FileNotFoundFileSystemStorage`\n- Custom and configurable error page views for: `400`, `403`, `404`, `500`\n- Custom management command with basic output feature `CustomBaseCommand`\n\n---\n\n## Models\n\n### `BaseModel`\n\nThis is a common model. By default, `BaseModel` contains these fields:\n\n- `created_at`\n- `updated_at`\n- `status`\n\nWe are overriding the default manager. `BaseModel` uses `BaseModelQuerySet` as\nmanager, `BaseModelWithSoftDelete` uses `BaseModelWithSoftDeleteManager`.\nThere are 4 basic status types:\n\n```python\nSTATUS_OFFLINE = 0\nSTATUS_ONLINE = 1\nSTATUS_DELETED = 2\nSTATUS_DRAFT = 3\n```\n\nYou can make these queries:\n\n```python\n>>> Post.objects.deleted() # filters: status = STATUS_DELETED\n>>> Post.objects.actives() # filters: status = STATUS_ONLINE\n>>> Post.objects.offlines() # filters: status = STATUS_OFFLINE\n>>> Post.objects.drafts() # filters: status = STATUS_DRAFT\n```\n\n### `BaseModelWithSoftDelete`\n\nThis model inherits from `BaseModel` and provides fake deletion which is\nprobably called **SOFT DELETE**. This means, when you call model\u2019s `delete()`\nmethod or QuerySet\u2019s `delete()` method, it acts like delete action but never\ndeletes the data.\n\nJust sets the status field to `STATUS_DELETED` and sets `deleted_at` field to\n**NOW**.\n\nThis works exactly like Django\u2019s `delete()`. Broadcasts `pre_delete` and\n`post_delete` signals and returns the number of objects marked as deleted and\na dictionary with the number of deletion-marks per object type.\n\nYou can call `hard_delete()` method to delete an instance or a queryset\nactually.\n\n```python\n>>> Post.objects.all()\n\nSELECT \"blog_post\".\"id\",\n \"blog_post\".\"created_at\",\n \"blog_post\".\"updated_at\",\n \"blog_post\".\"status\",\n \"blog_post\".\"deleted_at\",\n \"blog_post\".\"author_id\",\n \"blog_post\".\"category_id\",\n \"blog_post\".\"title\",\n \"blog_post\".\"body\"\n FROM \"blog_post\"\n LIMIT 21\n\nExecution time: 0.000135s [Database: default]\n\n, , ]>\n\n>>> Category.objects.all()\n\nSELECT \"blog_category\".\"id\",\n \"blog_category\".\"created_at\",\n \"blog_category\".\"updated_at\",\n \"blog_category\".\"status\",\n \"blog_category\".\"deleted_at\",\n \"blog_category\".\"title\"\n FROM \"blog_category\"\n WHERE \"blog_category\".\"deleted_at\" IS NULL\n LIMIT 21\n\n]>\n\n>>> Category.objects.delete()\n(4, {'blog.Category': 1, 'blog.Post': 3})\n\n>>> Category.objects.all()\n # rows are still there! don\u2019t panic!\n\n>>> Category.objects.deleted()\n]>\n```\n\n`BaseModelWithSoftDeleteQuerySet` has these query options according to\n`status` field:\n\n- `.all()`\n- `.offlines()` : filters if `BaseModel.STATUS_OFFLINE` is set\n- `.actives()` : filters if `BaseModel.STATUS_ONLINE` is set\n- `.deleted()` : filters if `BaseModel.STATUS_DELETED` is set and `deleted_at` is not `NULL`\n- `.drafts()` : filters if `BaseModel.STATUS_DRAFT` is set\n- `.delete()` : soft delete on given object.\n- `.undelete()` : recover soft deleted on given object.\n- `.hard_delete()` : this is real delete. this method erases given object.\n\n\nWhen soft-delete enabled (*during model creation*), Django admin will\nautomatically use `CustomBaseModelAdminWithSoftDelete` which is inherited from:\n `CustomBaseModelAdmin` <- `admin.ModelAdmin`.\n\n---\n\n## Model Admins\n\n### `CustomBaseModelAdmin`, `CustomBaseModelAdminWithSoftDelete`\n\nInherits from `admin.ModelAdmin`. By default, adds `status` to `list_filter`.\nYou can disable this via setting `sticky_list_filter = None`. When model is\ncreated with `rake new:model...` or from management command, admin file is\nautomatically generated. \n\nExample for `Post` model admin.\n\n```python\nimport logging\n\nfrom django.contrib import admin\n\nfrom baseapp.admin import CustomBaseModelAdminWithSoftDelete\nfrom baseapp.utils import console\n\nfrom ..models import Post\n\n__all__ = ['PostAdmin']\n\nlogger = logging.getLogger('app')\nconsole = console(source=__name__)\n\n@admin.register(Post)\nclass PostAdmin(CustomBaseModelAdminWithSoftDelete):\n # sticky_list_filter = None\n # hide_deleted_at = False\n pass\n```\n\nBy default, `deleted_at` excluded from admin form like `created_at` and\n`updated_at` fields. You can also override this via `hide_deleted_at` attribute.\nComment/Uncomment lines according to your needs! This works only in `CustomBaseModelAdminWithSoftDelete`.\n\n`CustomBaseModelAdminWithSoftDelete` also comes with special admin action. You can\nrecover/make active (*undelete*) multiple objects like deleting items.\n\n---\n\n## MiddleWare\n\n### `CustomLocaleMiddleware`\n\nThis is mostly used for our custom projects. Injects `LANGUAGE_CODE` variable to\n`request` object. `/en/path/to/page/` sets `request.LANGUAGE_CODE` to `en` otherwise `tr`.\n\n```python\n# add this to your settings/base.py\nMIDDLEWARE += ['baseapp.middlewares.CustomLocaleMiddleware']\n```\n\n---\n\n## Custom Error Pages\n\nYou have browsable (only in development mode) and customizable error handler\nfunctions and html templates now!. Templates are under `templates/custom_errors/`\nfolder.\n\n---\n\n## Goodies\n\n### `HtmlDebugMixin`\n\n![Example view](screenshots/vb_baseapp-view.png \"Debug on view layer\")\n\n`self.hdbg(arg, arg, arg, ...)` method helps you to output/debug some data\nin view layer.\n\n```python\n# example view: index.py\n\nfrom django.views.generic import TemplateView\n\nfrom console import console\n\nfrom ..mixins import HtmlDebugMixin\nfrom ..utils import numerify\n\n__all__ = ['IndexView']\n\nconsole = console(source=__name__)\n\n\nclass IndexView(HtmlDebugMixin, TemplateView):\n template_name = 'index.html'\n\n def get_context_data(self, **kwargs):\n self.hdbg('This', 'is', 'an', 'example', 'of')\n self.hdbg('self.hdbg', 'usage')\n self.hdbg(self.request.META)\n kwargs = super().get_context_data(**kwargs)\n\n query_string_p = numerify(self.request.GET.get('p'))\n console(query_string_p, type(query_string_p))\n console.dir(self.request.user)\n return kwargs\n```\n\n`{% hdbg %}` tag added by default in to your `templates/base.html` and works\nonly if the `DEBUG` is `True`.\n\n```django\n{% load static i18n %}\n\n\n\n\n \n \n {% block title %}{% endblock %}\n {% if DJANGO_ENV == 'development' %}\n \n \n {% else %}\n \n \n {% endif %}\n \n \n {% block extra_css %}{% endblock %}\n \n\n\n {% hdbg %}\n {% block body %}{% endblock %}\n {% block extra_js %}{% endblock %}\n\n\n```\n\nIf you don\u2019t want to extend from `templates/base.html` you can use your\nown template. You just need to add `{% hdbg %}` tag in to your template.\n\n\n---\n\n## License\n\nThis project is licensed under MIT\n\n---\n\n## Contributer(s)\n\n* [U\u011fur \"vigo\" \u00d6zy\u0131lmazel](https://github.com/vigo) - Creator, maintainer\n\n---\n\n## Contribute\n\nAll PR\u2019s are welcome!\n\n1. `fork` (https://github.com/vbyazilim/django-vb-baseapp/fork)\n1. Create your `branch` (`git checkout -b my-features`)\n1. `commit` yours (`git commit -am 'Add killer features'`)\n1. `push` your `branch` (`git push origin my-features`)\n1. Than create a new **Pull Request**!\n\n---\n\n## Change Log\n\n**2019-08-07**\n\n- Initial Beta relase: 1.0.0\n\n---\n\n\n", "description_content_type": "text/markdown", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/vbyazilim/django-vb-baseapp", "keywords": "", "license": "MIT", "maintainer": "", "maintainer_email": "", "name": "django-vb-baseapp", "package_url": "https://pypi.org/project/django-vb-baseapp/", "platform": "", "project_url": "https://pypi.org/project/django-vb-baseapp/", "project_urls": { "Homepage": "https://github.com/vbyazilim/django-vb-baseapp" }, "release_url": "https://pypi.org/project/django-vb-baseapp/1.0.2/", "requires_dist": [ "vb-console" ], "requires_python": ">=3.6", "summary": "Magical app for django-vb-admin", "version": "1.0.2" }, "last_serial": 6003741, "releases": { "1.0.1": [ { "comment_text": "", "digests": { "md5": "8634aa3ac8fe9398e0d8f873e18d1741", "sha256": "5d6b1a11b23033d88fe5ab991558e5f1a9b72dcee858a11a6c6f66eb8ba57339" }, "downloads": -1, "filename": "django_vb_baseapp-1.0.1-py3-none-any.whl", "has_sig": false, "md5_digest": "8634aa3ac8fe9398e0d8f873e18d1741", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.0", "size": 102925, "upload_time": "2019-10-20T06:31:03", "url": "https://files.pythonhosted.org/packages/57/47/2422ccefe6971d307e41a59ef2d858bcbbac350b13034c58b0bbf12b83b2/django_vb_baseapp-1.0.1-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "1dd98daa95d4c7d3064903945344e556", "sha256": "f55ca134f2fc9fcdd68f9a9e93523185ff6fea336dc5c3e7b45dd4523d30f7db" }, "downloads": -1, "filename": "django-vb-baseapp-1.0.1.tar.gz", "has_sig": false, "md5_digest": "1dd98daa95d4c7d3064903945344e556", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.0", "size": 86192, "upload_time": "2019-10-20T06:31:06", "url": "https://files.pythonhosted.org/packages/76/78/6a3dcc309a3567232f1c119fcac380bc58bf268b4949a353766aebd5650e/django-vb-baseapp-1.0.1.tar.gz" } ], "1.0.2": [ { "comment_text": "", "digests": { "md5": "eaa17effbf67891593fdd4275cca138f", "sha256": "f086048aeed83c94168268bc9910de4b1b858fc547704f5ae3e8d26d8b779eb0" }, "downloads": -1, "filename": "django_vb_baseapp-1.0.2-py3-none-any.whl", "has_sig": false, "md5_digest": "eaa17effbf67891593fdd4275cca138f", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6", "size": 104861, "upload_time": "2019-10-20T18:15:53", "url": "https://files.pythonhosted.org/packages/40/c6/c4f2e8cda818b4316a39e3dbaba2b630d2286f73758bb0a86cc8e9f8a506/django_vb_baseapp-1.0.2-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "ec6883519aa70804941bc4ced7f6280c", "sha256": "cc32bbe9c15fa4f598012d21712070590e8500096290fc5e5875e14f3b9275c1" }, "downloads": -1, "filename": "django-vb-baseapp-1.0.2.tar.gz", "has_sig": false, "md5_digest": "ec6883519aa70804941bc4ced7f6280c", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6", "size": 88644, "upload_time": "2019-10-20T18:15:56", "url": "https://files.pythonhosted.org/packages/67/21/9eceb77dcab974ac6aed2867f553c53c70935f49965295ea08e08f4f3e0a/django-vb-baseapp-1.0.2.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "eaa17effbf67891593fdd4275cca138f", "sha256": "f086048aeed83c94168268bc9910de4b1b858fc547704f5ae3e8d26d8b779eb0" }, "downloads": -1, "filename": "django_vb_baseapp-1.0.2-py3-none-any.whl", "has_sig": false, "md5_digest": "eaa17effbf67891593fdd4275cca138f", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6", "size": 104861, "upload_time": "2019-10-20T18:15:53", "url": "https://files.pythonhosted.org/packages/40/c6/c4f2e8cda818b4316a39e3dbaba2b630d2286f73758bb0a86cc8e9f8a506/django_vb_baseapp-1.0.2-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "ec6883519aa70804941bc4ced7f6280c", "sha256": "cc32bbe9c15fa4f598012d21712070590e8500096290fc5e5875e14f3b9275c1" }, "downloads": -1, "filename": "django-vb-baseapp-1.0.2.tar.gz", "has_sig": false, "md5_digest": "ec6883519aa70804941bc4ced7f6280c", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6", "size": 88644, "upload_time": "2019-10-20T18:15:56", "url": "https://files.pythonhosted.org/packages/67/21/9eceb77dcab974ac6aed2867f553c53c70935f49965295ea08e08f4f3e0a/django-vb-baseapp-1.0.2.tar.gz" } ] }