Skip to content

Latest commit

 

History

History
140 lines (135 loc) · 11.1 KB

checklist-en.md

File metadata and controls

140 lines (135 loc) · 11.1 KB

1. Concept

  • Check if your app follows Unix philosophy: "Do one thing, and do it well".
  • Check if your app's description fits a few words. Examples:
    • django-taggit: django-taggit a simpler approach to tagging with Django.
    • django-js-reverse: Javascript URL handling for Django that doesn't hurt.
    • django-impersonate: Simple application to allow superusers to "impersonate" other non-superuser accounts.
  • Check if your app's description has the word "and", if so, try to break it in more apps.

2. Easy to install

  • Add a LICENSE file.
  • Distribute on PyPI:
  • Publish on Django Packages.
  • Install dependencies automatically:
    • Add dependencies on install_requires on setup.py.
    • Don't add Django to install_requires.
    • Don't pin versions with == on install_requires. Use >=.
  • Check if you need a Django app or a regular Python package:
  • Have sane and smart defaults:
    • Make it work by default.
    • Don't require copy and pasting of code snippets.
    • Don't do anything dangerous by default, like caching.
  • Require unsafe behavior to be explicit:
    • Don't show all if something isn't set, e.g., fields = None shouldn't mean all fields.
  • Have declarative settings to allow easy configuration:
    • Add a prefix to all settings of the app, like MYAPP_SETTING_KEY.
    • Convert hardcoded internal parameters to settings:
      • For example, AVATAR_MAX_SIZE of django-avatar could be hardcoded, but it's a setting.
    • If needed frequently by developers, allow behavior to be changed with just a change of settings.
    • If needed frequently by developers, accept custom classes and functions on settings via dotted path:
      • For example, django-taggit supports custom tag parsers via settings.
  • Support declarative pipelines for configurable workflows:
  • Provide default views with templates and URLs to allow the app to be easily included.
  • Have a friendly upgrade policy:
    • Deprecate before removing. Raise deprecation warnings, use Python warnings built-in module.
    • Don't rewrite migrations:
      • Users might depend on your old migration files because they ran it against their data in the past.
    • Keep a CHANGELOG.
    • Follow Semantic Versioning.
  • Give credit, have a AUTHORS file:
    • Check this script to generate AUTHORS file from git history.

3. Easy to use

4. Easy to integrate

  • Reduce integration discontinuities:
    • Break class behaviors into methods.
    • Separate class behaviors into mixins.
    • Isolate logic into helper modules with business functions and classes.
  • Use AppConfig:
    • Make sure app doesn't break when AppConfig is extended.
  • Provide default templates:
    • Don't put them directly into templates/, put into templates/app_name/.
    • Guarantee they can be changed by loading a custom one with the same path.
  • Provide template tags for presenting complex data:
    • Leave only presentation logic into template tags, break the rest of logic into helpers.
      • 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.
  • Provide default views:
    • Don't break the configurability of class-based views, allow existing Django views attrs and methods to be overridden.
    • Break views common logic into mixins.
  • Avoid built-in models if possible:
  • Break models common parts into abstract models.
  • Don't use model mixins, use abstract models:
  • When using Generic Foreign Keys, allow them to be overridden by direct FKs. Examples of implementations:
  • Isolate form field logic into form fields and widgets:
  • Isolate model field logic into model fields:
  • Isolate query logic into queryset methods, like filter, update and delete logic.
  • Isolate table-level behavior logic into managers methods, like create logic.
  • Isolate validation logic into validators.
  • Use context processors only for global logic.
  • Use middlewares only for global logic related to request-response cycle or current user.
  • Avoid signals spaghetti code.

5. Maintenance

  • Be transparent about bugs, especially security issues:
    • Add security warnings to CHANGELOG, make sure they're parseable by safety tool.
  • Don't abandon the project, give it away.