{"id":43879854,"url":"https://github.com/nowells/django-pluggables","last_synced_at":"2026-02-06T15:15:35.640Z","repository":{"id":651257,"uuid":"293718","full_name":"nowells/django-pluggables","owner":"nowells","description":"A design pattern for Django that allows you to build \"Pluggable\" Reusable Applications","archived":false,"fork":false,"pushed_at":"2016-08-11T13:55:08.000Z","size":4018,"stargazers_count":95,"open_issues_count":1,"forks_count":8,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-11-29T12:17:40.881Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nowells.png","metadata":{"files":{"readme":"README.rst","changelog":"CHANGES","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2009-08-31T22:26:49.000Z","updated_at":"2025-10-10T20:13:38.000Z","dependencies_parsed_at":"2022-07-05T06:01:49.648Z","dependency_job_id":null,"html_url":"https://github.com/nowells/django-pluggables","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/nowells/django-pluggables","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nowells%2Fdjango-pluggables","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nowells%2Fdjango-pluggables/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nowells%2Fdjango-pluggables/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nowells%2Fdjango-pluggables/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nowells","download_url":"https://codeload.github.com/nowells/django-pluggables/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nowells%2Fdjango-pluggables/sbom","scorecard":{"id":695801,"data":{"date":"2025-08-11","repo":{"name":"github.com/nowells/django-pluggables","commit":"5d176f9377f487702484097aa5f35896d8a58353"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3,"checks":[{"name":"Code-Review","score":0,"reason":"Found 0/26 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 5 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-22T03:39:30.494Z","repository_id":651257,"created_at":"2025-08-22T03:39:30.494Z","updated_at":"2025-08-22T03:39:30.494Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29166366,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-06T14:37:12.680Z","status":"ssl_error","status_checked_at":"2026-02-06T14:36:22.973Z","response_time":59,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-02-06T15:15:34.904Z","updated_at":"2026-02-06T15:15:35.635Z","avatar_url":"https://github.com/nowells.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"###################\n Django-Pluggables\n###################\nDjango-Pluggables provides a design pattern for making reusable apps \"pluggable\" so that apps can exist at multiple URL locations and be presented by other apps or models.\n\nOverview\n========\nDjango-Pluggables is a design pattern that endows reusable applications with a few additional features:\n\n#. Applications can exist at multiple URL locations (e.g. http://example.com/foo/app/ and http://example.com/bar/app/).\n#. Applications can be \"parented\" to other applications or objects which can then deliver specialized context information.\n#. Posting form data and error handling can happen in locations that make sense to the user, as opposed to the common practice of using templatetags and standalone error or preview pages for form data processing.\n#. Views and templates remain generic and reusable.\n\nInstallation\n============\n\nDjango-Pluggables can be added to your Django project like any other reusable app. To see the examples in action, fun the following commands:\n\nFirst off, the native Mac implementation of sed is not as robust as we expect. Therefore install `Super Sed \u003chttp://sed.sourceforge.net/grabbag/ssed/\u003e`_  Then run ::\n\n   $ easy_install Fabric==0.1.1 pip virtualenv\n   $ fab bootstrap\n   $ ./examples/sillywalks/manage.py runserver\n\nVoila! You now have a fully functional site running at http://127.0.0.1:8000/\n\nUsage\n=====\n\nTo utilize Django-Pluggables, you will need to do a little bit of configuration. First you must have a two applications:\n\n#. A reusable app that will be made Pluggable.\n#. An app that will expose an instance of the Pluggable app in its URL hierarchy (this app does not need to be reusable).\n\nInstallation and development of these two apps can begin normally. The individual functions of the apps should be standalone. The Django-Pluggables pattern delivers needed context and parameters to the app that is being made Pluggable when it is called from the URL hierarchy of the other app.\n\nTo set up the relationship between these two apps, it is necessary to define two items:\n\n#. The URLconf that defines the URLs that will invoke the Pluggable app instance.\n#. The pluggable definition that will supply the Pluggable app with its required context and parameters.\n\n.. note::\n\n    In the following examples we will use two imaginary apps: ``sillywalks`` and ``complaints``. These would be imported in your modules like so::\n\n        from sillywalks.models import Walk\n        from complaints.models import Complaint\n\n    In the examples we discuss below, the ``sillywalks`` app lives at the URL::\n\n        http://example.com/sillywalks/\n\n    The ``sillywalks`` app utilizes the ``complaints`` app to field complaints about various types of walk. To provide an excellent user experience, the ``complaints`` forms and functionality should be presented at a URL beneath the ``sillywalks`` URL::\n\n        http://example.com/sillywalks/\u003cwalk_name\u003e/complaints/\n\n    Also, the presentation of ``complaints`` functionality beneath the ``sillywalks`` app should adhere to the ``sillywalks`` templates pattern, including various walk-specific information that must be supplied through additional, non- ``complaints`` app context.\n\nDefining the URLconf\n--------------------\nIn order to make the ``complaints`` app pluggable, we first must define a pluggable URLs file for it::\n\n    class ComplaintsPluggable(PluggableApp):\n        urlpatterns = patterns('',\n            url(r'^$', 'complaints.views.view_complaint', name='complaints_view_complaint'),\n            url(r'^activity_feed/$', 'complaints.views.submit_complaint', name='complaints_submit_complaint'),\n\n    ...\n\n.. note::\n\n    Only one pluggable URLs file is required for an app that you wish to make pluggable. This URLconf may be subclassed for additional flexibility when using the pluggable app in conjunction with other apps, but it is likely that one definition of pluggable URLs will be sufficient for most use cases.\n\nDefining the Pluggable Config and Context\n-----------------------------------------\n\nOnce the ``complaints`` app has been set up with the pluggable URLs, it is necessary to define the context that will be delivered to the ``complaints`` app and add these URLs to the URLconf for the ``sillywalks`` app::\n\n    from complaints.urls import ComplaintsPluggable\n\n    class SillyWalkComplaints(ComplaintsPluggable):\n        def pluggable_view_context(self, request, complaint_id):\n            return dict(complaint_id=complaint_id)\n\n        def pluggable_template_context(self, request, slug):\n            return dict(silly_walk=SillyWalk.objects.get(slug=slug))\n\n        def pluggable_config(self):\n            return dict(base_template='sillywalks/base.html')\n\n    urlpatterns = SillyWalkComplaints('sillywalk')\n\nMore\n====\n\nThe primary repository for Django-Pluggables is located at:\n\n`http://github.com/nowells/django-pluggables/ \u003chttp://github.com/nowells/django-pluggables/\u003e`_\n\nDjango-Pluggables was created by Nowell Strite.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnowells%2Fdjango-pluggables","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnowells%2Fdjango-pluggables","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnowells%2Fdjango-pluggables/lists"}