├── .gitignore ├── README.md ├── checklist-en.md ├── checklist-pt-br.md └── checklist-zh.md /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![alt text](https://s3-sa-east-1.amazonaws.com/www.vinta.com.br/images/dont_delete/devchecklist-logo.png "Devchecklists Logo") 2 | 3 | # Django Apps Checklist 4 | 5 | ## Adding a New Language: 6 | * [ ] Fork this repository; 7 | * [ ] To add a new language you will need to create another markdown file containing the new [acronym language:](https://www.loc.gov/standards/iso639-2/php/code_list.php) 8 | * E.g. `checklist-es.md`. 9 | * [ ] Submit a pull request for the forked repository; 10 | * [ ] The new checklist language should be visible on Devckecklists after we approve and merge your pull request. 11 | 12 | ## Important Notes: 13 | * [ ] Markdown is the only way to write checklists on Devchecklists; 14 | * [ ] For tips about how to use markdown to write checklists, please take a look at these raw files: 15 | * [ ] [`checklist-en.md`](https://raw.githubusercontent.com/vintasoftware/devchecklists-template/master/checklist-en.md) sample markdown; 16 | * [ ] [`README.md`](https://raw.githubusercontent.com/vintasoftware/devchecklists-template/master/README.md) contained on this repository; 17 | * [ ] Another checklists markdowns from [Devchecklists](https://devchecklists.com). 18 | * [ ] Changes on the checklist repository will reflect on the current checklist of Devchecklists. 19 | 20 | ## Commercial Support 21 | [![alt text](https://avatars2.githubusercontent.com/u/5529080?s=200&v=4 "Vinta Logo")](https://vintasoftware.com) 22 | 23 | This project, as other Vinta open-source projects, is used in products of Vinta clients. We are always looking for exciting work, so if you need any commercial support, feel free to get in touch: contact@vinta.com.br 24 | 25 | Copyright (c) 2018 Vinta Serviços e Soluções Tecnológicas Ltda. 26 | [MIT License](LICENSE.txt) 27 | -------------------------------------------------------------------------------- /checklist-en.md: -------------------------------------------------------------------------------- 1 | ## 1. Concept 2 | * [ ] Check if your app follows [Unix philosophy](https://en.wikipedia.org/wiki/Unix_philosophy): "Do one thing, and do it well". 3 | * [ ] Check if your app's description fits a few words. Examples: 4 | * [django-taggit](https://github.com/alex/django-taggit): django-taggit a simpler approach to tagging with Django. 5 | * [django-js-reverse](https://github.com/ierror/django-js-reverse): Javascript URL handling for Django that doesn't hurt. 6 | * [django-impersonate](https://bitbucket.org/petersanchez/django-impersonate): Simple application to allow superusers to "impersonate" other non-superuser accounts. 7 | * [ ] Check if your app's description has the word "and", if so, try to break it in more apps. 8 | 9 | ## 2. Easy to install 10 | * [ ] Add a [LICENSE](https://choosealicense.com/) file. 11 | * [ ] [Distribute on PyPI:](https://packaging.python.org/distributing/) 12 | * [ ] Check for name clashes to avoid problems like [django-filter](https://pypi.python.org/pypi/django-filter) vs [django-filters.](https://pypi.python.org/pypi/django-filters) 13 | * [ ] Use [Wheels.](https://packaging.python.org/distributing/#wheels) 14 | * [ ] Publish on [Django Packages.](https://djangopackages.org/) 15 | * [ ] Install dependencies automatically: 16 | * [ ] Add dependencies on `install_requires` on setup.py. 17 | * [ ] Don't add Django to `install_requires`. 18 | * [ ] Don't pin versions with `==` on `install_requires`. Use `>=`. 19 | * [ ] Check if you need a Django app or a regular Python package: 20 | * Django apps need to be added to `INSTALLED_APPS`. Regular Python packages do not. 21 | * Examples of regular Python packages: 22 | * [django-templated-email.](https://github.com/vintasoftware/django-templated-email) 23 | * [django-hashid-field.](https://github.com/nshafer/django-hashid-field) 24 | * [django-downloadview.](https://github.com/benoitbryon/django-downloadview) 25 | * [ ] Have sane and smart defaults: 26 | * [ ] Make it work by default. 27 | * [ ] Don't require copy and pasting of code snippets. 28 | * [ ] Don't do anything dangerous by default, like caching. 29 | * [ ] Require unsafe behavior to be explicit: 30 | * Don't show all if something isn't set, e.g., `fields = None` shouldn't mean all fields. 31 | * [ ] Have declarative settings to allow easy configuration: 32 | * [ ] Add a prefix to all settings of the app, like `MYAPP_SETTING_KEY`. 33 | * [ ] Convert hardcoded internal parameters to settings: 34 | * For example, `AVATAR_MAX_SIZE` of [django-avatar](http://django-avatar.readthedocs.io/en/latest/#AVATAR_MAX_SIZE) could be hardcoded, but it's a setting. 35 | * [ ] If needed frequently by developers, allow behavior to be changed with just a change of settings. 36 | * [ ] If needed frequently by developers, accept custom classes and functions on settings via dotted path: 37 | * For example, [django-taggit](https://django-taggit.readthedocs.io/en/latest/custom_tagging.html#using-a-custom-tag-string-parser) supports custom tag parsers via settings. 38 | * [ ] Support declarative pipelines for configurable workflows: 39 | * Check a implementation at [python-social-auth.](http://python-social-auth-docs.readthedocs.io/en/latest/configuration/django.html#personalized-configuration) 40 | * [ ] Provide default views with templates and URLs to allow the app to be easily included. 41 | * [ ] Have a friendly upgrade policy: 42 | * [ ] Deprecate before removing. Raise deprecation warnings, use Python [warnings](https://docs.python.org/3/library/warnings.html) built-in module. 43 | * [ ] Don't rewrite migrations: 44 | * Users might depend on your old migration files because they ran it against their data in the past. 45 | * [ ] [Keep a CHANGELOG.](http://keepachangelog.com/) 46 | * [ ] Follow [Semantic Versioning.](http://semver.org/) 47 | * [ ] Give credit, have a [AUTHORS file:](https://github.com/django/django/blob/master/AUTHORS) 48 | * Check this [script](https://kev.inburke.com/kevin/easy-maintenance-of-your-authors-file/) to generate AUTHORS file from git history. 49 | 50 | ## 3. Easy to use 51 | * [ ] Provide documentation: 52 | * [ ] Write docs first. 53 | * [ ] Have a README. 54 | * [ ] Provide a quick start tutorial describing the most common use case. 55 | * [ ] Separate high level from low-level docs. 56 | * [ ] Use gender neutral pronouns. 57 | * [ ] Host it in [Read the Docs.](http://readthedocs.org/) 58 | * [ ] Write tests: 59 | * [ ] Test with a [custom user model.](https://docs.djangoproject.com/en/dev/topics/auth/customizing/#specifying-a-custom-user-model) 60 | * [ ] Provide [coverage.](http://coverage.readthedocs.io/en/latest/) 61 | * [ ] Have Continuous Integration: 62 | * [ ] Use [tox](https://tox.readthedocs.io/en/latest/) to test against various Python and Django versions. 63 | * Check tox.ini of popular projects like [django-filter](https://github.com/carltongibson/django-filter/blob/develop/tox.ini) and [django-taggit.](https://github.com/alex/django-taggit/blob/master/tox.ini) 64 | * [ ] Respect PEP 8, use [flake8.](https://gitlab.com/pycqa/flake8) 65 | * [ ] Ship with an example project: 66 | * Examples of implementations: 67 | * [django-guardian.](https://github.com/django-guardian/django-guardian/tree/devel/example_project) 68 | * [django-haystack.](https://github.com/django-haystack/django-haystack/tree/master/example_project) 69 | * [django-avatar.](https://github.com/grantmcconnaughey/django-avatar/tree/master/test_proj) 70 | * [ ] Separate Django abstractions into [commonly used filenames](https://gist.github.com/fjsj/65ecfec09cfd2a684d53294d01677b9b) like views.py, forms.py, fields.py, etc. 71 | * [ ] Follow the pattern `resource_action` in URLs names, like `password_reset` or `product_detail`. 72 | * [ ] Never rely on Django default user model, support [custom user models:](https://docs.djangoproject.com/en/dev/topics/auth/customizing/#specifying-a-custom-user-model) 73 | * Check a implementation at [django-registration.](http://django-registration.readthedocs.io/en/latest/custom-user.html) 74 | * [ ] Provide declarative usage: 75 | * Examples of implementations: 76 | * [django-filter filtersets.](https://django-filter.readthedocs.io/en/develop/guide/usage.html#generating-filters-with-meta-fields) 77 | * [django-import-export resources.](http://django-import-export.readthedocs.io/en/latest/getting_started.html#advanced-data-manipulation) 78 | * [ ] Don't connect code implicitly by name or module. Have a registry: 79 | * Examples of implementations: 80 | * [django-contrib-comments moderator registry.](http://django-contrib-comments.readthedocs.io/en/latest/moderation.html#module-django_comments.moderation) 81 | * [django-activity-stream registry.](http://django-activity-stream.readthedocs.io/en/latest/configuration.html) 82 | * [ ] Have management commands for common developer needs: 83 | * Examples of implementations: 84 | * [django-reversion commands.](http://django-reversion.readthedocs.io/en/latest/commands.html) 85 | * [django-haystack commands.](http://django-haystack.readthedocs.io/en/latest/tutorial.html) 86 | * [ ] Use `_default_manager`, not `objects`, when interacting with models of the host project. 87 | * [ ] Be Pythonic: 88 | * [ ] Use generators for lazy evaluation. 89 | * [ ] Use `with` statement contexts to deal with unmanaged resources. 90 | * [ ] Prevent errors: 91 | * [ ] Provide checks with [Django System check framework.](https://docs.djangoproject.com/en/dev/topics/checks/) 92 | * [ ] Fail-fast: 93 | * [ ] Raise `ImproperlyConfigured` if the developer makes a mistake on the config: 94 | * For example, [django-filter raises `ImproperlyConfigured`](https://github.com/carltongibson/django-filter/blob/0883cb6b25cd3bb2fa337fb9c54f0a3d2159f676/django_filters/views.py#L18-L28) when the developer forgets to specify `filterset_class` or `model` in a `FilterView`. 95 | * [ ] Raise `TypeError` or `ValueError` when the app gets an invalid argument. 96 | 97 | - [ ] [Internationalize](https://docs.djangoproject.com/en/dev/topics/i18n/translation/) (I18N) your strings. 98 | 99 | ## 4. Easy to integrate 100 | * [ ] Reduce integration discontinuities: 101 | * [ ] Break class behaviors into methods. 102 | * [ ] Separate class behaviors into mixins. 103 | * [ ] Isolate logic into helper modules with business functions and classes. 104 | * [ ] Use [`AppConfig`:](https://docs.djangoproject.com/en/dev/ref/applications/) 105 | * [ ] Make sure app doesn't break when AppConfig is extended. 106 | * [ ] Provide default templates: 107 | * [ ] Don't put them directly into `templates/`, put into `templates/app_name/`. 108 | * [ ] Guarantee they can be changed by loading a custom one with the same path. 109 | * [ ] Provide template tags for presenting complex data: 110 | * [ ] Leave only presentation logic into template tags, break the rest of logic into helpers. 111 | * For example, django-avatar has a `avatar` template tag to generate HTML `img` tags, but the logic to generate avatar URLs is [isolated at `providers.py`.](https://github.com/grantmcconnaughey/django-avatar/blob/master/avatar/providers.py) 112 | * [ ] Provide default views: 113 | * [ ] Don't break the configurability of class-based views, allow existing Django views attrs and methods to be overridden. 114 | * [ ] Break views common logic into mixins. 115 | * [ ] Avoid built-in models if possible: 116 | * [ ] If you need to have them, provide an abstract model and allow your app to work with a concrete custom variety. Examples of implementations: 117 | * [django-taggit custom tag model.](https://django-taggit.readthedocs.io/en/latest/custom_tagging.html#custom-tag) 118 | * [django-blog-zinnia custom entry model.](http://docs.django-blog-zinnia.com/en/develop/how-to/extending_entry_model.html) 119 | * [django-contrib-comments custom app.](https://django-contrib-comments.readthedocs.io/en/latest/custom.html) 120 | * [ ] Break models common parts into abstract models. 121 | * [ ] Don't use model mixins, use abstract models: 122 | * Check the reason on this [StackOverflow answer.](http://stackoverflow.com/a/25817237/145349) 123 | * [ ] When using Generic Foreign Keys, allow them to be overridden by direct FKs. Examples of implementations: 124 | * [django-guardian support of direct foreign keys.](http://django-guardian.readthedocs.io/en/latest/userguide/performance.html#direct-foreign-keys) 125 | * [django-taggit support of custom through model.](https://django-taggit.readthedocs.io/en/latest/custom_tagging.html#custom-foreignkeys) 126 | * [ ] Isolate form field logic into form fields and widgets: 127 | * Check a implementation at [django-recaptcha.](https://github.com/praekelt/django-recaptcha) 128 | * [ ] Isolate model field logic into model fields: 129 | * Check a implementation at [django-hashid-field.](https://github.com/nshafer/django-hashid-field) 130 | * [ ] Isolate query logic into queryset methods, like filter, update and delete logic. 131 | * [ ] Isolate table-level behavior logic into managers methods, like create logic. 132 | * [ ] Isolate validation logic into validators. 133 | * [ ] Use context processors only for global logic. 134 | * [ ] Use middlewares only for global logic related to request-response cycle or current user. 135 | * [ ] Avoid signals spaghetti code. 136 | 137 | ## 5. Maintenance 138 | * [ ] Be transparent about bugs, especially security issues: 139 | * [ ] Add security warnings to CHANGELOG, make sure they're parseable by [safety](https://github.com/pyupio/safety) tool. 140 | * [ ] Don't abandon the project, give it away. 141 | -------------------------------------------------------------------------------- /checklist-pt-br.md: -------------------------------------------------------------------------------- 1 | ## 1. Conceitos 2 | * [ ] Verifique se seu app segue a [filosofia Unix](https://en.wikipedia.org/wiki/Unix_philosophy): "Faça uma coisa, e faça bem"; 3 | * [ ] Verifique se a descrição do seu app encaixa em poucas palavras. Exemplos: 4 | * [ ] [django-taggit](https://github.com/alex/django-taggit): django-taggit a simpler approach to tagging with Django; 5 | * [ ] [django-js-reverse](https://github.com/ierror/django-js-reverse): Javascript URL handling for Django that doesn't hurt; 6 | * [ ] [django-impersonate](https://bitbucket.org/petersanchez/django-impersonate): Simple application to allow superusers to "impersonate" other non-superuser accounts. 7 | * [ ] Verifique se a descrição do seu app tem a palavra "e", e caso tenha, tente quebrar em mais aplicações. 8 | 9 | ## 2. Fácil para Instalar 10 | * [ ] Crie um arquivo [LICENSE](https://choosealicense.com/); 11 | * [ ] [Distribua no PyPI:](https://packaging.python.org/distributing/) 12 | * [ ] Nome com prefixo `django-`; 13 | * [ ] Cheque conflito de nomes; 14 | * [ ] Mau exemplo de [django-filter](https://pypi.python.org/pypi/django-filter) vs [django-filters;](https://pypi.python.org/pypi/django-filters) 15 | * [ ] Use [Wheels.](https://packaging.python.org/distributing/#wheels) 16 | * [ ] Publique em [Django Packages;](https://djangopackages.org/) 17 | * [ ] Instale dependências automaticamente: 18 | * [ ] Adicione dependências em `install_requires` no setup.py; 19 | * [ ] Não adicione Django em `install_requires`; 20 | * [ ] Não coloque versões com `==` em `install_requires`. Use `>=`. 21 | * [ ] Verifique se você precisa de uma aplicação Django ou um pacote Python regular; 22 | * [ ] Aplicações Django precisam ser adicionados em `INSTALLED_APPS`. Pacotes python não; 23 | * [ ] Exemplos de pacotes Python: 24 | * [ ] [django-templated-email.](https://github.com/vintasoftware/django-templated-email) 25 | * [ ] [django-hashid-field.](https://github.com/nshafer/django-hashid-field) 26 | * [ ] [django-downloadview.](https://github.com/benoitbryon/django-downloadview) 27 | * [ ] Tenha padrões sensatos e inteligentes: 28 | * [ ] Torne-o um padrão; 29 | * [ ] Não obrigue copiar e colar de trechos de código; 30 | * [ ] Não faça nada perigoso por padrão, como caching. 31 | * [ ] Exija que o comportamento inseguro seja explícito: 32 | * Não exiba tudo se algo não estiver definido, exemplo: `fields = None` não deve significar todos os campos. 33 | * [ ] Tenha propriedades declarativas para habilitar uma fácil configuração: 34 | * [ ] Adicione um prefixo para todas as propriedades da aplicação, como `MYAPP_SETTING_KEY`; 35 | * [ ] Converta parâmetros internos hardcoded para propriedades: 36 | * [ ] Por exemplo, `AVATAR_MAX_SIZE` do [django-avatar](http://django-avatar.readthedocs.io/en/latest/#AVATAR_MAX_SIZE) deve ser hardcoded, mas ele é uma configuração; 37 | * [ ] Se é necessário frequentemente por desenvolvedores, habilite o comportamento para ser alterado com somente uma alteração na configuração; 38 | * [ ] Se é necessário frequentemente por desenvolvedores, aceite classes customizadas e funções nas configurações via dotted path; 39 | * Por exemplo, [django-taggit](https://django-taggit.readthedocs.io/en/latest/custom_tagging.html#using-a-custom-tag-string-parser) suporta tag parsers customizados via configuração. 40 | * [ ] Suporte pipelines declarativos para workflows configuráveis; 41 | * [ ] Cheque a implementação de [python-social-auth;](http://python-social-auth-docs.readthedocs.io/en/latest/configuration/django.html#personalized-configuration) 42 | * [ ] Providencie views padronizados com templates e URLs para habilitar a aplicação para ser incluída facilmente; 43 | * [ ] Tenha uma política de upgrade amigável: 44 | * [ ] Torne deprecated antes de remover. Para raise deprecation warnings, use o módulo [warnings](https://docs.python.org/3/library/warnings.html) do Python. 45 | * [ ] Não reescreva migrações: 46 | * Os usuários podem depender dos seus antigos arquivos de migração, porque eles rodaram no passado. 47 | * [ ] [Mantenha um CHANGELOG;](http://keepachangelog.com/) 48 | * [ ] Siga o [Versionamento Semântico;](http://semver.org/) 49 | * [ ] Dê créditos, tenha um arquivo [AUTHORS:](https://github.com/django/django/blob/master/AUTHORS) 50 | * Verifique este [script](https://kev.inburke.com/kevin/easy-maintenance-of-your-authors-file/) para gerar um arquivo AUTHORS a partir do histórico do seu repositório GIT. 51 | 52 | ## 3. Fácil de Usar 53 | * [ ] Providencie uma documentação: 54 | * [ ] Escreva docs primeiro; 55 | * [ ] Tenha um README; 56 | * [ ] Providencie um tutorial quick start descrevendo os casos mais comuns; 57 | * [ ] Separe documentação de alto e baixo nível; 58 | * [ ] Use pronomes de gênero neutros; 59 | * [ ] Hospede isso em [Read the Docs.](http://readthedocs.org/) 60 | * [ ] Escreva testes: 61 | * [ ] Teste com um [custom user model;](https://docs.djangoproject.com/en/dev/topics/auth/customizing/#specifying-a-custom-user-model) 62 | * [ ] Providencie uma [cobertura de código.](http://coverage.readthedocs.io/en/latest/) 63 | * [ ] Tenha uma Integração Contínua: 64 | * [ ] Use [tox](https://tox.readthedocs.io/en/latest/) para testar com as mais variadas versões de Python e django 65 | * Cheque o tox.ini de projetos populares como [django-filter](https://github.com/carltongibson/django-filter/blob/develop/tox.ini) e [django-taggit;](https://github.com/alex/django-taggit/blob/master/tox.ini) 66 | * [ ] Respeite o PEP 8, use [flake8.](https://gitlab.com/pycqa/flake8) 67 | * [ ] Envie com um projeto de exemplo. Exemplos de implementações: 68 | * [ ] [django-guardian;](https://github.com/django-guardian/django-guardian/tree/devel/example_project) 69 | * [ ] [django-haystack;](https://github.com/django-haystack/django-haystack/tree/master/example_project) 70 | * [ ] [django-avatar.](https://github.com/grantmcconnaughey/django-avatar/tree/master/test_proj) 71 | * [ ] Separe abstrações Django em nomes de [arquivos comumente usados](https://gist.github.com/fjsj/65ecfec09cfd2a684d53294d01677b9b) como views.py, forms.py, fields.py, etc; 72 | * [ ] Siga o padrão `resource_action` em nomes de URLs, como `password_reset` ou `product_detail`; 73 | * [ ] Nunca confie em modelos de usuário padrão, suporte [custom user models:](https://docs.djangoproject.com/en/dev/topics/auth/customizing/#specifying-a-custom-user-model) 74 | * Cheque a implementação de [django-registration.](http://django-registration.readthedocs.io/en/latest/custom-user.html) 75 | 76 | * [ ] Providencie uso declarativo. Exemplo de implementações: 77 | * [ ] [django-filter filtersets;](https://django-filter.readthedocs.io/en/develop/guide/usage.html#generating-filters-with-meta-fields) 78 | * [ ] [django-import-export resources.](http://django-import-export.readthedocs.io/en/latest/getting_started.html#advanced-data-manipulation) 79 | 80 | * [ ] Não conecte código implicitamente pelo nome ou módulo. Tenha um registry. Exemplos de implementações: 81 | * [ ] [django-contrib-comments moderator registry;](http://django-contrib-comments.readthedocs.io/en/latest/moderation.html#module-django_comments.moderation) 82 | * [ ] [django-activity-stream registry.](http://django-activity-stream.readthedocs.io/en/latest/configuration.html) 83 | 84 | * [ ] Tenha comandos management para necessidades em comum de desenvolvedores. Exemplo de implementações: 85 | * [ ] [django-reversion commands;](http://django-reversion.readthedocs.io/en/latest/commands.html) 86 | * [ ] [django-haystack commands.](http://django-haystack.readthedocs.io/en/latest/tutorial.html) 87 | * [ ] Use `_default_manager`, não `objects`, quando interagir com models do projeto host; 88 | * [ ] Seja pythônico: 89 | * [ ] Use generators para lazy evaluation; 90 | * [ ] Use declarações de contexto `with` para lidar com recursos não gerenciados. 91 | 92 | * [ ] Previna erros: 93 | * [ ] Providencie checks com [Django System check framework.](https://docs.djangoproject.com/en/dev/topics/checks/) 94 | 95 | * [ ] Falha rápida: 96 | * [ ] Dispare `ImproperlyConfigured` se o desenvolvedor cometer erros na configuração. 97 | * [ ] [django-filter dispara `ImproperlyConfigured`](https://github.com/carltongibson/django-filter/blob/0883cb6b25cd3bb2fa337fb9c54f0a3d2159f676/django_filters/views.py#L18-L28) quando o desenvolvedor esquece de especificar `filterset_class` ou `model` no `FilterView`; 98 | * [ ] Dispare `TypeError` ou `ValueError` quando a aplicação obtém um argumento inválido. 99 | * [ ] [Internacionalize](https://docs.djangoproject.com/en/dev/topics/i18n/translation/) (I18N) seus strings. 100 | 101 | ## 4. Fácil para integrar 102 | * [ ] Reduza descontinuidades na integração: 103 | * [ ] Quebrar comportamentos de classes dentro de métodos; 104 | * [ ] Separar comportamento de classes dentro de mixins; 105 | * [ ] Isolar lógica dentro de módulos helper com funções e classes de negócio. 106 | * [ ] [Use `AppConfig`:](https://docs.djangoproject.com/en/dev/ref/applications/) 107 | * [ ] Verifique se seu aplicativo não interrompe quando o AppConfig é estendido. 108 | * [ ] Providencie templates padrão: 109 | * [ ] Não coloque diretamente dentro de `templates/`, mas coloque dentro de `templates/app_name/`; 110 | * [ ] Garanta que podem ser alterados carregando algum template personalizando com o mesmo caminho. 111 | * [ ] Providencie template tags para apresentar dados complexos 112 | * [ ] Deixe apenas lógica de apresentação dentro de template tags, quebre o resto da lógica dentro de helpers. Por exemplo: 113 | * [ ] django-avatar tem um `avatar` template tag para gerar tags `img`, mas a lógica para gerar URLs avatar é [isolado em `providers.py`;](https://github.com/grantmcconnaughey/django-avatar/blob/master/avatar/providers.py) 114 | * [ ] Providencie views padrão: 115 | * [ ] Não quebre a configurabilidade dos class-based views. Permita que os atributos e métodos existentes nas views do Django sejam sobrescritos; 116 | * [ ] Quebre lógica de views em comum dentro de mixins. 117 | * [ ] Evite models built-in se possível. Caso precise tê-los, providencie um model abstrato e habilite sua aplicação de trabalhar com uma variedade de customizados concretos. Exemplos de implementação: 118 | * [ ] [django-taggit custom tag model;](https://django-taggit.readthedocs.io/en/latest/custom_tagging.html#custom-tag) 119 | * [ ] [django-blog-zinnia custom entry model;](http://docs.django-blog-zinnia.com/en/develop/how-to/extending_entry_model.html) 120 | * [ ] [django-contrib-comments custom app;](https://django-contrib-comments.readthedocs.io/en/latest/custom.html) 121 | * [ ] Quebre partes comuns de models dentro de models abstratos; 122 | * [ ] Não use model mixins, use models abstratos: 123 | * Cheque a razão disso em [StackOverflow answer.](http://stackoverflow.com/a/25817237/145349) 124 | * [ ] Quando usar Generic Foreign Keys, permita que eles sejam substituídos por FKs diretas. Exemplos de implementação: 125 | * [ ] [django-guardian support of direct foreign keys;](http://django-guardian.readthedocs.io/en/latest/userguide/performance.html#direct-foreign-keys) 126 | * [ ] [django-taggit support of custom through model.](https://django-taggit.readthedocs.io/en/latest/custom_tagging.html#custom-foreignkeys) 127 | * [ ] Isole lógica de campos form dentro de form fields e widgets: 128 | * Cheque a implementação em [django-recaptcha.](https://github.com/praekelt/django-recaptcha) 129 | * [ ] Isole e lógica de campos model dentro de model fields: 130 | * Cheque a implementação em [django-hashid-field.](https://github.com/nshafer/django-hashid-field) 131 | * [ ] Isole lógica de query dentro de métodos queryset, como filter, update e delete; 132 | * [ ] Isole lógica de comportamente a nível de tabela, dentro de métodos manager, como lógica do create; 133 | * [ ] Isole lógica de validação dentro de validators; 134 | * [ ] Use context processors somente para lógicas globais; 135 | * [ ] Use middlewares somente para lógicas globais relacionados ao ciclo request-response ou current user; 136 | * [ ] Evite código spathetti nos signals. 137 | 138 | ## 5. Manutenção 139 | * [ ] Seja transparente sobre bugs, especialmente problemas de segurança; 140 | * [ ] Adicione warnings de segurança no CHANGELOG. Certifique-se de que eles são analisáveis por [ferramentas de segurança;](https://github.com/pyupio/safety) 141 | * [ ] Não abandone o projeto, give it away. 142 | -------------------------------------------------------------------------------- /checklist-zh.md: -------------------------------------------------------------------------------- 1 | ## 1. 概念 2 | * [ ] 检查你的应用是否遵循 [Unix 哲学](https://zh.wikipedia.org/wiki/Unix%E5%93%B2%E5%AD%A6): "让程序只做好一件事" 3 | * [ ] 检查你的应用是否可以被一句话描述,参考: 4 | * [django-taggit](https://github.com/alex/django-taggit): 一个易用的基于 Django 的打标签方案 5 | * [django-js-reverse](https://github.com/ierror/django-js-reverse): 针对 Django 的 Javascript 链接处理应用 6 | * [django-impersonate](https://bitbucket.org/petersanchez/django-impersonate): 一个用于使超级用户可以"冒充"其他普通用户的应用 7 | * [ ] 检查你的应用描述是否介绍多个功能,如果是的话,请将其拆解为多个应用 8 | 9 | ## 2. 易于安装 10 | * [ ] 添加 [许可证](https://choosealicense.com/) 文件 11 | * [ ] [在 PyPI 上发布](https://packaging.python.org/distributing/): 12 | * [ ] 检查命名冲突以避免像 [django-filter](https://pypi.python.org/pypi/django-filter) 和 [django-filters](https://pypi.python.org/pypi/django-filters) 的问题 13 | * [ ] 使用 [Wheels](https://packaging.python.org/distributing/#wheels) 14 | * [ ] 在 [Django Packages](https://djangopackages.org/) 上发布 15 | * [ ] 自动安装依赖库: 16 | * [ ] 在 setup.py 文件中的 `install_requires` 添加依赖 17 | * [ ] 不要在 `install_requires` 中添加 Django 18 | * [ ] 不要在 `install_requires` 中使用 `==` 限制版本,请使用 `>=` 19 | * [ ] 确认你需要一个 Django 应用还是一个常规的 Python 库: 20 | * Django 应用需要被添加至 `INSTALLED_APPS` 中,常规 Python 库不需用添加 21 | * 一些常规的 Python 库: 22 | * [django-templated-email](https://github.com/vintasoftware/django-templated-email) 23 | * [django-hashid-field](https://github.com/nshafer/django-hashid-field) 24 | * [django-downloadview](https://github.com/benoitbryon/django-downloadview) 25 | * [ ] 包含健全及设计良好的默认值: 26 | * [ ] 默认即可运行 27 | * [ ] 不要要求开发者复制粘贴代码片段 28 | * [ ] 默认不要做危险的操作,如,缓存 29 | * [ ] 危险操作需要被显式的定义: 30 | * 不要在未设置时默认显式全部,例如,`fields = None` 不代表所有 fields 31 | * [ ] 使用明确的 settings 以简化配置: 32 | * [ ] 为此应用的所有设置添加前缀,例如,`MYAPP_SETTING_KEY` 33 | * [ ] 将硬编码的内部参数替换为配置: 34 | * 例如,[django-avatar](http://django-avatar.readthedocs.io/en/latest/#AVATAR_MAX_SIZE) 中的 `AVATAR_MAX_SIZE` 可以被硬编码,但他被定义为单个配置 35 | * [ ] 如果开发者经常需要调整行为,也请在配置中调整 36 | * [ ] 如果开发者经常需要调整自定义类或函数,也请在配置中通过路径设置: 37 | * 例如,[django-taggit](https://django-taggit.readthedocs.io/en/latest/custom_tagging.html#using-a-custom-tag-string-parser) 在 settings 中设置自定义 tag 解析器 38 | * [ ] 请使用管道声明的方式设置工作流: 39 | * 请查看 [python-social-auth](http://python-social-auth-docs.readthedocs.io/en/latest/configuration/django.html#personalized-configuration) 的实现 40 | * [ ] 提供默认 views,templates 和 URLs 以简化应用的集成 41 | * [ ] 提供友好的升级策略: 42 | * [ ] 删除前先弃用一段时间,抛出弃用警告,使用 Python 内建模块 [warnings](https://docs.python.org/3/library/warnings.html) 43 | * [ ] 不要改写旧的 migrations: 44 | * 用户已在他们的数据集上运行了你那旧的 migration 文件 45 | * [ ] [维护更新日志](http://keepachangelog.com/) 46 | * [ ] 遵循 [语义化版本控制](http://semver.org/) 47 | * [ ] 给参与者以鼓励,提供 [作者清单](https://github.com/django/django/blob/master/AUTHORS): 48 | * 基于 git 历史记录,使用 [脚本](https://kev.inburke.com/kevin/easy-maintenance-of-your-authors-file/) 生成作者清单 49 | 50 | ## 3. 易于使用 51 | * [ ] 提供文档: 52 | * [ ] 先写文档 53 | * [ ] 提供自述文件 54 | * [ ] 提供快速入门教程,其中包含常见的使用案例 55 | * [ ] 区分高级和初级内容 56 | * [ ] 使用性别中立的人称代词 57 | * [ ] 部署在 [Read the Docs](http://readthedocs.org/) 上 58 | * [ ] 提供测试: 59 | * [ ] 测试 [custom user model](https://docs.djangoproject.com/en/dev/topics/auth/customizing/#specifying-a-custom-user-model) 60 | * [ ] 提供 [coverage](http://coverage.readthedocs.io/en/latest/) 61 | * [ ] 提供持续集成: 62 | * [ ] 使用 [tox](https://tox.readthedocs.io/en/latest/) 在不同 Python 及 Django 版本下测试 63 | * 参考热门项目的 tox.ini 文件,例如,[django-filter](https://github.com/carltongibson/django-filter/blob/develop/tox.ini) 和 [django-taggit](https://github.com/alex/django-taggit/blob/master/tox.ini) 64 | * [ ] 遵循 PEP 8 规范,使用 [flake8](https://gitlab.com/pycqa/flake8) 65 | * [ ] 提供样例工程: 66 | * 一些实现如下: 67 | * [django-guardian](https://github.com/django-guardian/django-guardian/tree/devel/example_project) 68 | * [django-haystack](https://github.com/django-haystack/django-haystack/tree/master/example_project) 69 | * [django-avatar](https://github.com/grantmcconnaughey/django-avatar/tree/master/test_proj) 70 | * [ ] 将应用以 Django 的抽象方式分成 [常用文件名](https://gist.github.com/fjsj/65ecfec09cfd2a684d53294d01677b9b) 像 views.py,forms.py,fields.py 等 71 | * [ ] 在 URLs 命名中遵循模式 `resource_action`,例如, `password_reset`, `product_detail` 72 | * [ ] 绝不依赖 Django 默认的用户模型,支持 [自定义用户模型](https://docs.djangoproject.com/en/dev/topics/auth/customizing/#specifying-a-custom-user-model): 73 | * 参考 [django-registration](http://django-registration.readthedocs.io/en/latest/custom-user.html) 的实现 74 | * [ ] 提供明确的用法: 75 | * 一些实现如下: 76 | * [django-filter filtersets](https://django-filter.readthedocs.io/en/develop/guide/usage.html#generating-filters-with-meta-fields) 77 | * [django-import-export resources](http://django-import-export.readthedocs.io/en/latest/getting_started.html#advanced-data-manipulation) 78 | * [ ] 不要隐式的绑定代码与名称或模块,提供注册机制: 79 | * 一些实现如下: 80 | * [django-contrib-comments moderator registry](http://django-contrib-comments.readthedocs.io/en/latest/moderation.html#module-django_comments.moderation) 81 | * [django-activity-stream registry](http://django-activity-stream.readthedocs.io/en/latest/configuration.html) 82 | * [ ] 为开发者提供常用的管理命令: 83 | * 一些实现如下: 84 | * [django-reversion commands](http://django-reversion.readthedocs.io/en/latest/commands.html) 85 | * [django-haystack commands](http://django-haystack.readthedocs.io/en/latest/tutorial.html) 86 | * [ ] 和主项目交互时,请使用 `_default_manager` 而不是 `objects` 87 | * [ ] Be Pythonic: 88 | * [ ] 使用生成器进行惰性求值 89 | * [ ] 使用上下文管理语句 `with` 处理未管理的资源 90 | * [ ] 预防错误: 91 | * [ ] 基于 [Django System check framework](https://docs.djangoproject.com/en/dev/topics/checks/) 提供检查脚本 92 | * [ ] 快速失败: 93 | * [ ] 如果开发者写错配置文件,抛出 `ImproperlyConfigured` 异常: 94 | * 例如,当开发者忘记在 `FilterView` 中指定 `filterset_class` 或 `model` 时,[django-filter raises `ImproperlyConfigured`](https://github.com/carltongibson/django-filter/blob/0883cb6b25cd3bb2fa337fb9c54f0a3d2159f676/django_filters/views.py#L18-L28) 95 | * [ ] 当应用传入了不合法的参数时,抛出 `TypeError` 或 `ValueError` 96 | 97 | - [ ] [国际化](https://docs.djangoproject.com/en/dev/topics/i18n/translation/) (I18N) 你的字符串 98 | 99 | ## 4. 易于集成 100 | * [ ] 保证集成的连续性: 101 | * [ ] 将类行为由不同方法实现 102 | * [ ] 拆解类行为至 mixins 103 | * [ ] 将业务函数或类中的逻辑拆解至帮助模块中 104 | * [ ] 使用 [`AppConfig`](https://docs.djangoproject.com/en/dev/ref/applications/): 105 | * [ ] 确保扩展 AppConfig 时,应用不会出错 106 | * [ ] 提供默认模板: 107 | * [ ] 不要将他们直接放在 `templates/` 下,放在对应 `templates/app_name/` 下 108 | * [ ] 确保开发者自定义模板时,相同路径下的模板可以被覆盖 109 | * [ ] 提供模板标签去呈现复杂的数据: 110 | * [ ] 只在模板标签中保留展示逻辑,其他逻辑请移入帮助模块 111 | * 例如,django-avatar 有一个 `avatar` 模板标签用于生成 HTML `img` 标签,但是生成头像路径的逻辑 [独立于 `providers.py`](https://github.com/grantmcconnaughey/django-avatar/blob/master/avatar/providers.py) 112 | * [ ] 提供默认的视图: 113 | * [ ] 不要破坏 class-based views 的可配置性,保持 Django views 的属性和方法可以被重载 114 | * [ ] 提取通用的 views 逻辑至 mixins 115 | * [ ] 尽可能避免使用内建的 models: 116 | * [ ] 如果必须使用,请提供一个 abstract model,并为你的应用提供对应的变种实现,一些实现如下: 117 | * [django-taggit custom tag model](https://django-taggit.readthedocs.io/en/latest/custom_tagging.html#custom-tag) 118 | * [django-blog-zinnia custom entry model](http://docs.django-blog-zinnia.com/en/develop/how-to/extending_entry_model.html) 119 | * [django-contrib-comments custom app](https://django-contrib-comments.readthedocs.io/en/latest/custom.html) 120 | * [ ] 提取通用的 models 至 abstract models 121 | * [ ] 不要使用 model mixins,使用 abstract models: 122 | * 原因见 [StackOverflow answer](http://stackoverflow.com/a/25817237/145349) 123 | * [ ] 通用外键应该可以被直接外键覆盖,一些实现如下: 124 | * [django-guardian support of direct foreign keys](http://django-guardian.readthedocs.io/en/latest/userguide/performance.html#direct-foreign-keys) 125 | * [django-taggit support of custom through model](https://django-taggit.readthedocs.io/en/latest/custom_tagging.html#custom-foreignkeys) 126 | * [ ] 隔离 form field 逻辑至 form fields 和 widgets: 127 | * 参考 [django-recaptcha](https://github.com/praekelt/django-recaptcha) 128 | * [ ] 隔离 model field 逻辑至 model fields: 129 | * 参考 [django-hashid-field](https://github.com/nshafer/django-hashid-field) 130 | * [ ] 隔离查询逻辑至 queryset,如,filter,update 和 delete 131 | * [ ] 隔离表级别逻辑至 managers,如,create 132 | * [ ] 隔离校验逻辑至 validators 133 | * [ ] 只把 context processors 用于全局逻辑 134 | * [ ] 只把 middlewares 用于涉及全局逻辑的请求-响应循环或当前用户 135 | * [ ] 使用 signals 以避免意大利面式代码 136 | 137 | ## 5. 维护 138 | * [ ] 坦率的对待 bugs,尤其是安全问题: 139 | * [ ] 在变更日志中加入安全警告,确保他们可以被 [safety](https://github.com/pyupio/safety) 解析 140 | * [ ] 不要废弃项目,可以捐给社区 141 | --------------------------------------------------------------------------------