{ "info": { "author": "Leo Neto", "author_email": "leo@ekletik.com", "bugtrack_url": null, "classifiers": [ "Environment :: Web Environment", "Framework :: Django", "Intended Audience :: Developers", "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3 :: Only", "Topic :: Software Development :: Libraries :: Application Frameworks", "Topic :: Software Development :: Libraries :: Python Modules" ], "description": "Djangle-CLI [WIP]\n\nCLI that handles creating and managing Django projects\n\n#### Requirements\n[Requirements](requirements.txt)\n\n\n#### Installation\nInstall via [pip](http://www.pip-installer.org/):\n```\npip install djangle-cli\n```\n\nInstall from source:\n```\ngit clone https://github.com/oleoneto/djangle.git\ncd djangle\npip install .\n```\n\n----\n\n#### Commands\n```\ndestroy Removes models, serializers, and other...\ngenerate Adds models, routes, and other resources\nnew Creates projects and apps\n```\n\n----\n\n## New\nThe `new` command (abbreviated `n`) can be used to start new projects as well as new applications. The command tries to simplify how a project is created as well as the applications contained in it. Here's an example of such simplification:\n\nSuppose you want to start a new project and want to create two apps within it:\n```\ndjango-admin startproject API\ncd API/API/\ndjango-admin startapp developers\ndjango-admin startapp blog\n```\n\nThe equivalent command in the Djangle-CLI is:\n```\nD new project API developers blog\n```\nSpecifying an `app` when creating a project is optional, but you're likely to need to create one inside of your project directory, so the CLI can handle the creation of all of your apps as arguments after your project name.\n\n#### Project structure\nThis CLI makes some assumptions about the structure of your Django project.\n1. It assumes that your apps are one level below the root of your project directory, one level below where `manage.py` is. For example:\n```\nPROJECT\n\u251c\u2500\u2500 PROJECT\n\u2502\u00a0\u00a0 \u251c\u2500\u2500 __init__.py\n\u2502\u00a0\u00a0 \u251c\u2500\u2500 My_Application_1\n\u2502\u00a0\u00a0 \u251c\u2500\u2500 My_Application_2\n\u2502\u00a0\u00a0 \u251c\u2500\u2500 settings.py\n\u2502\u00a0\u00a0 \u251c\u2500\u2500 urls.py\n\u2502\u00a0\u00a0 \u2514\u2500\u2500 wsgi.py\n\u251c\u2500\u2500 manage.py\n\u2514\u2500\u2500 requirements.txt\n```\n2. It assumes that your app resources are grouped together by type in packages. For example:\n```\nMy_Application_1\n\u251c\u2500\u2500 __init__.py\n\u251c\u2500\u2500 admin\n\u251c\u2500\u2500 apps.py\n\u251c\u2500\u2500 forms\n\u251c\u2500\u2500 migrations\n\u251c\u2500\u2500 models\n\u251c\u2500\u2500 serializers\n\u251c\u2500\u2500 templates\n\u251c\u2500\u2500 tests\n\u251c\u2500\u2500 urls.py\n\u251c\u2500\u2500 views\n\u2514\u2500\u2500 viewsets\n```\n3. Each class representing a `model`, `serializer`, `viewset`, or `form` is located in its own Python file. For example:\n```\nmodels/\n\u251c\u2500\u2500 album.py\n\u251c\u2500\u2500 book.py\n\u2514\u2500\u2500 person.py\n```\n\nThis is done in order to aid the CLI with the creation and deletion of files\nin the project as we'll see under the [`generate`](#generator) and [`destroy`](#destroyer) commands.\n\n----\n\n## Generator\n\nThe generator is accessible through the `generate` command (abbreviated `g`).\nIt can be used to create the following:\n- **form**\n- **model**\n- **serializer**\n- **view**\n- **viewset**\n- **template**\n\nIf you need all of the above, you can use the **resource** sub-command instead of running the individual sub-commands listed above.\n\nThe generator supports `--dry-run`, meaning it can provide you with the console log\nof the desired command without creating any files in your directory structure.\nThis is useful if you want to see what a command accomplishes before fully committing to it.\n\n**Note**: no current support for `--dry-run` when scaffolding a **resource**.\n\n#### Generating Models\nIn order to generate a model, specify the type identifier and then the name of the attribute field. Type identifiers are abbreviated to a more generic name that omits the word `Field`. The input here is case-insensitive, but the fields will be properly CamelCased in the corresponding Python file as in the example below:\n\n```bash\nD generate model album text:title image:artwork bool:is_compilation\n```\n\nThis would add the following model `album.py` under the `models` directory:\n```python\nimport uuid\nfrom django.db import models\n\n\nclass Album(models.Model):\n title = models.TextField(blank=True)\n artwork = models.ImageField(blank=True, upload_to='uploads')\n compilation = models.BooleanField(default=False)\n\n # Default fields. Used for record-keeping.\n uuid = models.UUIDField(default=uuid.uuid4, editable=False)\n created_at = models.DateTimeField(auto_now_add=True, editable=False)\n updated_at = models.DateTimeField(auto_now=True, editable=False)\n\n class Meta:\n db_table = 'app_name_albums'\n ordering = ['-created_at']\n\n def save(self, *args, **kwargs):\n super().save(*args, **kwargs)\n\n def __str__(self):\n return f'{self.uuid}\n```\n**Defaults**\n\nAs one can see, `class Meta` and `_str_` are added to a model by default along with `uuid`, `created_at` and `updated_at` fields.\nThe `db_table` name is inferred from the name of the app and the current model while the ordering attribute is defined based on the default `created_at` field.\n\n\n**Relationships**\n\nIf a relationship identifier is passed, the attribute name will be used as the name of the model it relates to.\nSpecifying a relationship also adds an import statement to the model file. For example:\n```bash\nD generate model album fk:artist\n```\n\nWould create an `artist` attribute like so:\n```python\nimport uuid\nfrom django.db import models\nfrom .artist import Artist\n\nclass Album(models.Model):\n artist = models.ForeignKey(Artist, related_name='albums', on_delete=models.DO_NOTHING)\n\n # Default fields. Used for record-keeping.\n uuid = models.UUIDField(default=uuid.uuid4, editable=False)\n created_at = models.DateTimeField(auto_now_add=True, editable=False)\n updated_at = models.DateTimeField(auto_now=True, editable=False)\n\n class Meta:\n db_table = 'album'\n ordering = ['-created_at']\n\n def save(self, *args, **kwargs):\n super().save(*args, **kwargs)\n\n def __str__(self):\n return f'{self.uuid}'\n```\n\nSupported relationship identifiers:\n- **FK**: ForeignKeyField\n- **One**: OneToOneField\n- **Many**: ManyToManyField\n\n#### Generating Serializers and Viewsets\nIf you are working on an API and use the `Django REST Framework` to support your backend, you can also use the Djangle-CLI to create `serializers` and `viewsets`.\n\nThe commands are much like the ones used to generate a model except you don't specify any model attributes, just the model name:\n```bash\nD generate serializer album\n```\n\nWhich outputs:\n```python\nfrom rest_framework import serializers\nfrom ..models.album import Album\n\n\nclass AlbumSerializer(serializers.ModelSerializer):\n\n # Add related fields below:\n # Example relation fields are:\n # -- HyperlinkedIdentityField\n # -- HyperlinkedRelatedField\n # -- PrimaryKeyRelatedField\n # -- SlugRelatedField\n # -- StringRelatedField\n\n # You can also create a custom serializer, like so:\n # likes = LikeSerializer(many=True)\n\n class Meta:\n model = Album\n fields = \"__all__\"\n```\n\nSimilarly, a `viewset` can be generated like so:\n\n```bash\nD generate viewset album\n```\n\nWhich in turn would generate the following `viewset`:\n```python\nfrom rest_framework import viewsets\nfrom rest_framework import permissions\nfrom ..models.album import Album\nfrom ..serializers.album import AlbumSerializer\n\n\nclass AlbumViewSet(viewsets.ModelViewSet):\n queryset = Album.objects.all()\n serializer_class = AlbumSerializer\n permission_classes = [permissions.IsAuthenticatedOrReadOnly]\n```\n\n----\n\n## Destroyer [WIP]\nThis command can be used to undo all that a generator can generate.\nSo, following our example `Album` model, one can remove it from the project simply by running:\n\n```bash\nD destroy model album\n```\n\n**Supported options:**\n- **form**\n- **model**\n- **resource**\n- **view**\n- **viewset**\n- **serializer**\n- **template**\n\n----\n\n### To Do\n[Check open issues.](https://github.com/oleoneto/djangle/issues)\n\n----\n\n### Pull requests\nThis project is a work in progress. Contributions are very much welcome.\n\n----\n\n### LICENSE\n**Djangle-CLI** is [MIT Licensed](LICENSE).", "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/oleoneto/djangle", "keywords": "django automate cli command line tools rails ember python framework devops", "license": "BSD", "maintainer": "", "maintainer_email": "", "name": "djangle-cli", "package_url": "https://pypi.org/project/djangle-cli/", "platform": "any", "project_url": "https://pypi.org/project/djangle-cli/", "project_urls": { "Documentation": "https://github.com/oleoneto/djangle/", "Homepage": "https://github.com/oleoneto/djangle", "Source Code": "https://github.com/oleoneto/djangle/" }, "release_url": "https://pypi.org/project/djangle-cli/0.0.2/", "requires_dist": null, "requires_python": "", "summary": "CLI for managing Django projects", "version": "0.0.2" }, "last_serial": 5325190, "releases": { "0.0.1": [ { "comment_text": "", "digests": { "md5": "23a1b25ab6206b6c5da008252daeb7e1", "sha256": "20da9dbcf043a3d6d490b678b0c807dfdc39fac583d5de06b0d458af9272fb52" }, "downloads": -1, "filename": "Djangle CLI-0.0.1.tar.gz", "has_sig": false, "md5_digest": "23a1b25ab6206b6c5da008252daeb7e1", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 20330, "upload_time": "2019-05-27T01:59:18", "url": "https://files.pythonhosted.org/packages/46/04/7ace8690848da9abb26b02cf081e958108d003fb84029d6c7efdaa21d504/Djangle%20CLI-0.0.1.tar.gz" } ], "0.0.2": [ { "comment_text": "", "digests": { "md5": "d62c51038e3cdde99fd5fd8cf9dbee7b", "sha256": "d99e0b736fd6384202ada52c18de7c778de380d49caef35231bce9eb1a18d17e" }, "downloads": -1, "filename": "djangle-cli-0.0.2.tar.gz", "has_sig": false, "md5_digest": "d62c51038e3cdde99fd5fd8cf9dbee7b", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 24107, "upload_time": "2019-05-28T06:03:38", "url": "https://files.pythonhosted.org/packages/b3/a7/f8152c9e05edb2483e21d92eb493f3775ece3a62fdf42eb4bafee62308f1/djangle-cli-0.0.2.tar.gz" } ], "0.0.2a0": [ { "comment_text": "", "digests": { "md5": "9aa8213121926eff87d81ab881bd49f9", "sha256": "63144cac67c9d78f3199bd9635f330b89ef46972ee4d3624c8e506dfb740fd7c" }, "downloads": -1, "filename": "djangle-cli-0.0.2a0.tar.gz", "has_sig": false, "md5_digest": "9aa8213121926eff87d81ab881bd49f9", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 23814, "upload_time": "2019-05-28T04:44:32", "url": "https://files.pythonhosted.org/packages/6a/1a/cf165c485f84a4511ebf9b51649f1a75a0b7708b48d22740d10fd7d922a0/djangle-cli-0.0.2a0.tar.gz" } ], "0.0a3": [ { "comment_text": "", "digests": { "md5": "a1ecdc2b6776e890868297708b7a6a7c", "sha256": "990363a468b7271decc2290d8270f126e3ea9ecb34701f6580f755ac035757e0" }, "downloads": -1, "filename": "djangle-cli-0.0a3.tar.gz", "has_sig": false, "md5_digest": "a1ecdc2b6776e890868297708b7a6a7c", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 23814, "upload_time": "2019-05-28T06:03:45", "url": "https://files.pythonhosted.org/packages/d7/b8/cdb84b4894b0de912bb6cfb93c4b0ab62ccf409aa4ca282da82a9f92b34f/djangle-cli-0.0a3.tar.gz" } ], "0.0a4": [ { "comment_text": "", "digests": { "md5": "6660a2ad8bb1a584695b2ab1d80edc8f", "sha256": "e031f5cd50541d078e73ea1cd0f01c608c90614b617d63a10581798b73886ec9" }, "downloads": -1, "filename": "djangle-cli-0.0a4.tar.gz", "has_sig": false, "md5_digest": "6660a2ad8bb1a584695b2ab1d80edc8f", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 24053, "upload_time": "2019-05-28T06:03:47", "url": "https://files.pythonhosted.org/packages/eb/44/9526f4081320202ba12b80a464f1c569c399d3c772c0145b9adc38b2eaa7/djangle-cli-0.0a4.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "d62c51038e3cdde99fd5fd8cf9dbee7b", "sha256": "d99e0b736fd6384202ada52c18de7c778de380d49caef35231bce9eb1a18d17e" }, "downloads": -1, "filename": "djangle-cli-0.0.2.tar.gz", "has_sig": false, "md5_digest": "d62c51038e3cdde99fd5fd8cf9dbee7b", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 24107, "upload_time": "2019-05-28T06:03:38", "url": "https://files.pythonhosted.org/packages/b3/a7/f8152c9e05edb2483e21d92eb493f3775ece3a62fdf42eb4bafee62308f1/djangle-cli-0.0.2.tar.gz" } ] }