├── .coveragerc ├── .dockerignore ├── .github_changelog_generator ├── .gitignore ├── .travis.yml ├── CHANGELOG.md ├── Dockerfile ├── LICENSE ├── MANIFEST.in ├── Procfile ├── README.md ├── app.json ├── client ├── .babelrc ├── index.js ├── package-lock.json ├── package.json ├── server.js ├── styles.css └── webpack.config.js ├── docs ├── customization.md ├── img │ └── ui-screenshot.png ├── index.md ├── schema.md └── settings.md ├── example_app ├── README.md ├── __init__.py ├── manage.py ├── snippets │ ├── __init__.py │ ├── fixtures │ │ └── users.json │ ├── migrations │ │ ├── 0001_initial.py │ │ ├── 0002_auto_20160717_2140.py │ │ ├── 0003_auto_20160718_0720.py │ │ ├── 0004_auto_20180430_1036.py │ │ └── __init__.py │ ├── models.py │ ├── permissions.py │ ├── serializers.py │ └── views.py └── tutorial │ ├── __init__.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py ├── mkdocs.yml ├── pylintrc ├── requirements.txt ├── rest_framework_swagger ├── __init__.py ├── renderers.py ├── settings.py ├── static │ └── rest_framework_swagger │ │ ├── bundles │ │ ├── app.bundle.css │ │ ├── app.bundle.js │ │ ├── vendors.bundle.css │ │ └── vendors.bundle.js │ │ ├── favicon-16x16.png │ │ ├── favicon-32x32.png │ │ └── logo_small.png ├── templates │ └── rest_framework_swagger │ │ └── index.html └── views.py ├── run_example.sh ├── runtests.py ├── runtime.txt ├── setup.cfg ├── setup.py ├── tests ├── __init__.py ├── compat │ ├── __init__.py │ └── mock.py ├── renderers │ ├── __init__.py │ ├── test_openapi_renderer.py │ └── test_swagger.py ├── settings.py ├── test_settings.py └── test_views.py └── tox.ini /.coveragerc: -------------------------------------------------------------------------------- 1 | [run] 2 | branch = True 3 | source = rest_framework_swagger 4 | 5 | [report] 6 | exclude_lines = 7 | pragma: no cover 8 | -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | .git 2 | .tox 3 | -------------------------------------------------------------------------------- /.github_changelog_generator: -------------------------------------------------------------------------------- 1 | since-tag=2.0.0 2 | future-release=2.2.0 3 | issues=false 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Extended from https://github.com/github/gitignore/blob/master/Python.gitignore 2 | *.py[cod] 3 | *$py.class 4 | 5 | # C extensions 6 | *.so 7 | 8 | # Distribution / packaging 9 | .Python 10 | env/ 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib64/ 18 | parts/ 19 | sdist/ 20 | var/ 21 | *.egg-info/ 22 | .installed.cfg 23 | *.egg 24 | 25 | # PyInstaller 26 | # Usually these files are written by a python script from a template 27 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 28 | *.manifest 29 | *.spec 30 | 31 | # Installer logs 32 | pip-log.txt 33 | pip-delete-this-directory.txt 34 | 35 | # Unit test / coverage reports 36 | htmlcov/ 37 | .tox/ 38 | .coverage 39 | .coverage.* 40 | .cache 41 | nosetests.xml 42 | coverage.xml 43 | *,cover 44 | .hypothesis/ 45 | 46 | # Translations 47 | *.mo 48 | *.pot 49 | 50 | # Django stuff: 51 | *.log 52 | local_settings.py 53 | 54 | # Flask stuff: 55 | instance/ 56 | .webassets-cache 57 | 58 | # Scrapy stuff: 59 | .scrapy 60 | 61 | # Sphinx documentation 62 | docs/_build/ 63 | 64 | # PyBuilder 65 | target/ 66 | 67 | # IPython Notebook 68 | .ipynb_checkpoints 69 | 70 | # pyenv 71 | .python-version 72 | 73 | # celery beat schedule file 74 | celerybeat-schedule 75 | 76 | # dotenv 77 | .env 78 | 79 | # virtualenv 80 | venv/ 81 | ENV/ 82 | 83 | # Spyder project settings 84 | .spyderproject 85 | 86 | # Rope project settings 87 | .ropeproject 88 | 89 | *.db 90 | site/ 91 | src/ 92 | 93 | node_modules/ 94 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: python 2 | python: 3 | - "3.6" 4 | - "2.7" 5 | sudo: false 6 | matrix: 7 | fast_finish: true 8 | install: 9 | - pip install tox tox-travis codecov 10 | script: 11 | - tox 12 | after_success: 13 | codecov 14 | 15 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | ## [2.2.0](https://github.com/marcgibbons/django-rest-swagger/tree/2.2.0) (2018-04-30) 4 | [Full Changelog](https://github.com/marcgibbons/django-rest-swagger/compare/2.1.2...2.2.0) 5 | 6 | **Merged pull requests:** 7 | 8 | - Spelling. [\#753](https://github.com/marcgibbons/django-rest-swagger/pull/753) ([vshih](https://github.com/vshih)) 9 | - Fix deploy on heroku error with a psycopg2 upgrade [\#742](https://github.com/marcgibbons/django-rest-swagger/pull/742) ([GabLeRoux](https://github.com/GabLeRoux)) 10 | - Fix build on heroku link in documentation ✌🏻 [\#740](https://github.com/marcgibbons/django-rest-swagger/pull/740) ([GabLeRoux](https://github.com/GabLeRoux)) 11 | - Correct filename [\#706](https://github.com/marcgibbons/django-rest-swagger/pull/706) ([williln](https://github.com/williln)) 12 | - Update schema.md [\#638](https://github.com/marcgibbons/django-rest-swagger/pull/638) ([knipknap](https://github.com/knipknap)) 13 | - Swagger UI version 3.13.6 [\#637](https://github.com/marcgibbons/django-rest-swagger/pull/637) ([marcgibbons](https://github.com/marcgibbons)) 14 | - Add security [\#636](https://github.com/marcgibbons/django-rest-swagger/pull/636) ([dimitrismakris](https://github.com/dimitrismakris)) 15 | - Update README.md [\#635](https://github.com/marcgibbons/django-rest-swagger/pull/635) ([KirovVerst](https://github.com/KirovVerst)) 16 | - Allow various Swagger spec fields to be overridden [\#626](https://github.com/marcgibbons/django-rest-swagger/pull/626) ([jonhermansen](https://github.com/jonhermansen)) 17 | - Release/2.1.2 [\#625](https://github.com/marcgibbons/django-rest-swagger/pull/625) ([marcgibbons](https://github.com/marcgibbons)) 18 | 19 | ## [2.1.2](https://github.com/marcgibbons/django-rest-swagger/tree/2.1.2) (2017-03-12) 20 | [Full Changelog](https://github.com/marcgibbons/django-rest-swagger/compare/2.1.1...2.1.2) 21 | 22 | **Merged pull requests:** 23 | 24 | - Add template block to override logo [\#624](https://github.com/marcgibbons/django-rest-swagger/pull/624) ([marcgibbons](https://github.com/marcgibbons)) 25 | - Add DRF 3.6, Python 3.6 to test suite [\#623](https://github.com/marcgibbons/django-rest-swagger/pull/623) ([marcgibbons](https://github.com/marcgibbons)) 26 | - Test against Django 1.11 [\#610](https://github.com/marcgibbons/django-rest-swagger/pull/610) ([edmorley](https://github.com/edmorley)) 27 | - Release/2.1.1 [\#606](https://github.com/marcgibbons/django-rest-swagger/pull/606) ([marcgibbons](https://github.com/marcgibbons)) 28 | 29 | ## [2.1.1](https://github.com/marcgibbons/django-rest-swagger/tree/2.1.1) (2017-01-06) 30 | [Full Changelog](https://github.com/marcgibbons/django-rest-swagger/compare/2.1.0...2.1.1) 31 | 32 | **Merged pull requests:** 33 | 34 | - Set zip\_safe as False [\#605](https://github.com/marcgibbons/django-rest-swagger/pull/605) ([jakul](https://github.com/jakul)) 35 | - @blueyed: doc api version authorization [\#598](https://github.com/marcgibbons/django-rest-swagger/pull/598) ([marcgibbons](https://github.com/marcgibbons)) 36 | - Restore swagger shortcut view [\#597](https://github.com/marcgibbons/django-rest-swagger/pull/597) ([marcgibbons](https://github.com/marcgibbons)) 37 | - optional urlconf [\#578](https://github.com/marcgibbons/django-rest-swagger/pull/578) ([theromis](https://github.com/theromis)) 38 | - Release 2.1.0 [\#576](https://github.com/marcgibbons/django-rest-swagger/pull/576) ([marcgibbons](https://github.com/marcgibbons)) 39 | 40 | ## [2.1.0](https://github.com/marcgibbons/django-rest-swagger/tree/2.1.0) (2016-10-29) 41 | [Full Changelog](https://github.com/marcgibbons/django-rest-swagger/compare/2.0.7...2.1.0) 42 | 43 | **Merged pull requests:** 44 | 45 | - simple fix in schema documentation [\#575](https://github.com/marcgibbons/django-rest-swagger/pull/575) ([drgarcia1986](https://github.com/drgarcia1986)) 46 | - 2.1.0: Make DRF 3.5 minimum version, use get\_schema\_view shortcut [\#570](https://github.com/marcgibbons/django-rest-swagger/pull/570) ([marcgibbons](https://github.com/marcgibbons)) 47 | - Minimum DRF version to 3.4.1 [\#566](https://github.com/marcgibbons/django-rest-swagger/pull/566) ([vinodc](https://github.com/vinodc)) 48 | - Release/2.0.7 [\#565](https://github.com/marcgibbons/django-rest-swagger/pull/565) ([marcgibbons](https://github.com/marcgibbons)) 49 | 50 | ## [2.0.7](https://github.com/marcgibbons/django-rest-swagger/tree/2.0.7) (2016-10-16) 51 | [Full Changelog](https://github.com/marcgibbons/django-rest-swagger/compare/2.0.6...2.0.7) 52 | 53 | **Merged pull requests:** 54 | 55 | - Swagger doc view shortcut [\#564](https://github.com/marcgibbons/django-rest-swagger/pull/564) ([marcgibbons](https://github.com/marcgibbons)) 56 | - Extend OpenAPI codec to accept extra dict [\#563](https://github.com/marcgibbons/django-rest-swagger/pull/563) ([marcgibbons](https://github.com/marcgibbons)) 57 | 58 | ## [2.0.6](https://github.com/marcgibbons/django-rest-swagger/tree/2.0.6) (2016-10-02) 59 | [Full Changelog](https://github.com/marcgibbons/django-rest-swagger/compare/2.0.5...2.0.6) 60 | 61 | **Merged pull requests:** 62 | 63 | - Add testing instructions \(Closes \#503\) [\#558](https://github.com/marcgibbons/django-rest-swagger/pull/558) ([marcgibbons](https://github.com/marcgibbons)) 64 | - PR \#554 [\#557](https://github.com/marcgibbons/django-rest-swagger/pull/557) ([marcgibbons](https://github.com/marcgibbons)) 65 | - Update dependency versions to latest. [\#556](https://github.com/marcgibbons/django-rest-swagger/pull/556) ([marcgibbons](https://github.com/marcgibbons)) 66 | - Docs fixup: METHOD -\> METHODS [\#550](https://github.com/marcgibbons/django-rest-swagger/pull/550) ([lwm](https://github.com/lwm)) 67 | - Release 2.0.6 [\#559](https://github.com/marcgibbons/django-rest-swagger/pull/559) ([marcgibbons](https://github.com/marcgibbons)) 68 | - Use minified swagger-ui.min.js [\#545](https://github.com/marcgibbons/django-rest-swagger/pull/545) ([coagulant](https://github.com/coagulant)) 69 | 70 | ## [2.0.5](https://github.com/marcgibbons/django-rest-swagger/tree/2.0.5) (2016-08-21) 71 | [Full Changelog](https://github.com/marcgibbons/django-rest-swagger/compare/2.0.4...2.0.5) 72 | 73 | **Merged pull requests:** 74 | 75 | - Use entrypoint for Dockerfile \#524. [\#532](https://github.com/marcgibbons/django-rest-swagger/pull/532) ([marcgibbons](https://github.com/marcgibbons)) 76 | - Feature/526 template overrides [\#531](https://github.com/marcgibbons/django-rest-swagger/pull/531) ([marcgibbons](https://github.com/marcgibbons)) 77 | - run\_example: fix "docker build" command [\#527](https://github.com/marcgibbons/django-rest-swagger/pull/527) ([blueyed](https://github.com/blueyed)) 78 | - Feature: exception handling [\#523](https://github.com/marcgibbons/django-rest-swagger/pull/523) ([marcgibbons](https://github.com/marcgibbons)) 79 | - Release/2.0.4 [\#521](https://github.com/marcgibbons/django-rest-swagger/pull/521) ([marcgibbons](https://github.com/marcgibbons)) 80 | 81 | ## [2.0.4](https://github.com/marcgibbons/django-rest-swagger/tree/2.0.4) (2016-08-16) 82 | [Full Changelog](https://github.com/marcgibbons/django-rest-swagger/compare/2.0.3...2.0.4) 83 | 84 | **Merged pull requests:** 85 | 86 | - Feature/517 fix bug when auth urls none [\#520](https://github.com/marcgibbons/django-rest-swagger/pull/520) ([marcgibbons](https://github.com/marcgibbons)) 87 | - Add basic UI settings [\#519](https://github.com/marcgibbons/django-rest-swagger/pull/519) ([marcgibbons](https://github.com/marcgibbons)) 88 | - Feature/auto detect hosts [\#516](https://github.com/marcgibbons/django-rest-swagger/pull/516) ([marcgibbons](https://github.com/marcgibbons)) 89 | - Upgrade template settings for 1.10 support in example app. [\#514](https://github.com/marcgibbons/django-rest-swagger/pull/514) ([marcgibbons](https://github.com/marcgibbons)) 90 | - Update test env settings. [\#513](https://github.com/marcgibbons/django-rest-swagger/pull/513) ([marcgibbons](https://github.com/marcgibbons)) 91 | - Heroku deployment of example\_app. [\#506](https://github.com/marcgibbons/django-rest-swagger/pull/506) ([marcgibbons](https://github.com/marcgibbons)) 92 | - 2.0.3 release [\#500](https://github.com/marcgibbons/django-rest-swagger/pull/500) ([marcgibbons](https://github.com/marcgibbons)) 93 | 94 | ## [2.0.3](https://github.com/marcgibbons/django-rest-swagger/tree/2.0.3) (2016-07-24) 95 | [Full Changelog](https://github.com/marcgibbons/django-rest-swagger/compare/2.0.2...2.0.3) 96 | 97 | **Merged pull requests:** 98 | 99 | - Feature/auth urls [\#499](https://github.com/marcgibbons/django-rest-swagger/pull/499) ([marcgibbons](https://github.com/marcgibbons)) 100 | 101 | ## [2.0.2](https://github.com/marcgibbons/django-rest-swagger/tree/2.0.2) (2016-07-20) 102 | [Full Changelog](https://github.com/marcgibbons/django-rest-swagger/compare/0.3.10...2.0.2) 103 | 104 | ## [0.3.10](https://github.com/marcgibbons/django-rest-swagger/tree/0.3.10) (2016-07-20) 105 | [Full Changelog](https://github.com/marcgibbons/django-rest-swagger/compare/0.3.9...0.3.10) 106 | 107 | **Merged pull requests:** 108 | 109 | - Support Release 0.3.10 [\#491](https://github.com/marcgibbons/django-rest-swagger/pull/491) ([marcgibbons](https://github.com/marcgibbons)) 110 | - 2.0.0a0 docs typo fixup [\#484](https://github.com/marcgibbons/django-rest-swagger/pull/484) ([lwm](https://github.com/lwm)) 111 | 112 | ## [0.3.9](https://github.com/marcgibbons/django-rest-swagger/tree/0.3.9) (2016-07-17) 113 | [Full Changelog](https://github.com/marcgibbons/django-rest-swagger/compare/2.0.1...0.3.9) 114 | 115 | **Merged pull requests:** 116 | 117 | - Release 0.3.9 [\#481](https://github.com/marcgibbons/django-rest-swagger/pull/481) ([marcgibbons](https://github.com/marcgibbons)) 118 | 119 | ## [2.0.1](https://github.com/marcgibbons/django-rest-swagger/tree/2.0.1) (2016-07-14) 120 | [Full Changelog](https://github.com/marcgibbons/django-rest-swagger/compare/2.0.0...2.0.1) 121 | 122 | 123 | 124 | \* *This Change Log was automatically generated by [github_changelog_generator](https://github.com/skywinder/Github-Changelog-Generator)* -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:3.5.2 2 | RUN mkdir /code 3 | ADD requirements.txt /code 4 | RUN pip install -r /code/requirements.txt 5 | ADD . /code 6 | WORKDIR /code/example_app 7 | VOLUME /code 8 | 9 | ENTRYPOINT bash -c "python manage.py migrate --noinput && python manage.py loaddata users && python manage.py runserver 0.0.0.0:8000" 10 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013-2016, Marc Gibbons 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | 1. Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 2. Redistributions in binary form must reproduce the above copyright notice, 10 | this list of conditions and the following disclaimer in the documentation 11 | and/or other materials provided with the distribution. 12 | 13 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 14 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 15 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 16 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 17 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 18 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 19 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 20 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 21 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 22 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include README.md 2 | include LICENSE 3 | 4 | global-exclude __pycache__ 5 | global-exclude *.pyc 6 | global-exclude *.pyo 7 | 8 | recursive-include rest_framework_swagger/static * 9 | recursive-include rest_framework_swagger/templates * 10 | -------------------------------------------------------------------------------- /Procfile: -------------------------------------------------------------------------------- 1 | web: cd example_app && gunicorn tutorial.wsgi 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Django REST Swagger: deprecated (2019-06-04) 2 | 3 | This project is no longer being maintained. Please consider **drf-yasg** as an alternative/successor. I haven't personally used it, but it looks feature-complete and is actively maintained. 4 | 5 | ### https://github.com/axnsan12/drf-yasg 6 | 7 | Thanks for all the support and contributions over the years. Special thanks to [Lights on Software](https://lightsonsoftware.com/), [Lincoln Loop](https://lincolnloop.com/) and BNOTIONS for generously donating time to work on this project :heart:. 8 | 9 | --- 10 | 11 | [![build-status-badge]][build-status] 12 | [![codecov](https://codecov.io/gh/marcgibbons/django-rest-swagger/branch/master/graph/badge.svg)](https://codecov.io/gh/marcgibbons/django-rest-swagger) 13 | [![pypi-version]][pypi] 14 | 15 | 16 | [![Deploy](https://www.herokucdn.com/deploy/button.svg)](https://heroku.com/deploy) 17 | 18 | 19 | #### An API documentation generator for Swagger UI and Django REST Framework 20 | 21 | Full documentation: http://marcgibbons.github.io/django-rest-swagger/ 22 | 23 | 24 | ## Installation 25 | 26 | 1. `pip install django-rest-swagger` 27 | 28 | 2. Add `rest_framework_swagger` to your `INSTALLED_APPS` setting: 29 | 30 | ```python 31 | INSTALLED_APPS = ( 32 | ... 33 | 'rest_framework_swagger', 34 | ) 35 | ``` 36 | 37 | ## Rendering Swagger Specification and Documentation 38 | 39 | This package ships with two renderer classes: 40 | 41 | 1. `OpenAPIRenderer` generates the OpenAPI (fka Swagger) JSON schema specification. This renderer will be presented if: 42 | - `Content-Type: application/openapi+json` is specified in the headers. 43 | - `?format=openapi` is passed as query param 44 | 2. `SwaggerUIRenderer` generates the Swagger UI and requires the `OpenAPIRenderer` 45 | 46 | 47 | ### Quick Start Example: 48 | ```python 49 | from django.conf.urls import url 50 | from rest_framework_swagger.views import get_swagger_view 51 | 52 | schema_view = get_swagger_view(title='Pastebin API') 53 | 54 | urlpatterns = [ 55 | url(r'^$', schema_view) 56 | ] 57 | ``` 58 | 59 | ## Requirements 60 | * Django 1.8+ 61 | * Django REST framework 3.5.1+ 62 | * Python 2.7, 3.5, 3.6 63 | 64 | 65 | ## Testing 66 | 67 | - Run `$ tox` to execute the test suite against all supported environments. 68 | - Run `./runtests.py` to run the test suite within the current environment. 69 | 70 | ## Bugs & Contributions 71 | Please report bugs by opening an issue 72 | 73 | Contributions are welcome and are encouraged! 74 | 75 | ## Special Thanks 76 | Many thanks to Tom Christie & all the contributors who have developed [Django REST Framework](http://django-rest-framework.org/) 77 | 78 | 79 | [build-status-badge]: https://travis-ci.org/marcgibbons/django-rest-swagger.svg?branch=master 80 | [build-status]: https://travis-ci.org/marcgibbons/django-rest-swagger 81 | [pypi-version]: https://img.shields.io/pypi/v/django-rest-swagger.svg 82 | [pypi]: https://pypi.python.org/pypi/django-rest-swagger 83 | [license]: https://pypi.python.org/pypi/django-rest-swagger/ 84 | [docs-badge]: https://readthedocs.io/projects/django-rest-swagger/badge/ 85 | [docs]: http://django-rest-swagger.readthedocs.io/ 86 | -------------------------------------------------------------------------------- /app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Django REST Swagger Example", 3 | "description": "An example of Django REST Swagger using the Django REST Framework Tutorial app", 4 | "repository": "https://github.com/marcgibbons/django-rest-swagger", 5 | "keywords": ["django", "swagger", "rest", "framework"], 6 | "env": { 7 | "HEROKU": "1", 8 | "DISABLE_COLLECTSTATIC": "1", 9 | "SECURE_SSL_REDIRECT": "1" 10 | }, 11 | "scripts": { 12 | "postdeploy": "python example_app/manage.py migrate --noinput && python example_app/manage.py loaddata users" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /client/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | "env", 4 | "stage-0" 5 | ] 6 | } 7 | -------------------------------------------------------------------------------- /client/index.js: -------------------------------------------------------------------------------- 1 | import SwaggerUI from 'swagger-ui' 2 | import 'swagger-ui/dist/swagger-ui.css'; 3 | import './styles.css'; 4 | 5 | let config = Object.assign( 6 | { 7 | dom_id: '#rest-swagger-ui', 8 | spec: window.drsSpec, 9 | }, 10 | window.drsSettings 11 | ); 12 | 13 | const csrfTokenInput = window.document.getElementsByName('csrfmiddlewaretoken'); 14 | 15 | // If present, set CSRF token to request headers 16 | if (csrfTokenInput.length) { 17 | const csrfToken = csrfTokenInput[0].value; 18 | config.requestInterceptor = (req) => { 19 | req.headers['X-CSRFToken'] = csrfToken; 20 | if (config.acceptHeaderVersion) { 21 | req.headers['accept'] += '; version=' + config.acceptHeaderVersion; 22 | } 23 | 24 | req.headers = Object.assign(req.headers, config.customHeaders); 25 | 26 | return req; 27 | } 28 | } 29 | 30 | 31 | window.swagger = SwaggerUI(config); 32 | -------------------------------------------------------------------------------- /client/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "django-rest-swagger", 3 | "version": "1.0.0", 4 | "description": "Template generation for Django REST Swagger", 5 | "main": "index.js", 6 | "scripts": { 7 | "build": "webpack", 8 | "test": "echo \"Error: no test specified\" && exit 1", 9 | "server": "NODE_ENV=dev node server.js" 10 | }, 11 | "author": "", 12 | "license": "ISC", 13 | "dependencies": { 14 | "swagger-ui": "^3.13.6" 15 | }, 16 | "devDependencies": { 17 | "babel-core": "^6.26.0", 18 | "babel-loader": "^7.1.4", 19 | "babel-preset-env": "^1.6.1", 20 | "babel-preset-stage-0": "^6.24.1", 21 | "clean-webpack-plugin": "^0.1.19", 22 | "css-loader": "^0.28.11", 23 | "http-proxy-middleware": "^0.18.0", 24 | "mini-css-extract-plugin": "^0.4.0", 25 | "style-loader": "^0.21.0", 26 | "webpack": "^4.6.0", 27 | "webpack-cli": "^2.0.15", 28 | "webpack-dev-middleware": "^3.1.3" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /client/server.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const proxy = require('http-proxy-middleware'); 3 | const webpack = require('webpack'); 4 | const webpackDevMiddleware = require('webpack-dev-middleware'); 5 | 6 | const app = express(); 7 | const config = require('./webpack.config.js'); 8 | const compiler = webpack(config); 9 | 10 | // Tell express to use the webpack-dev-middleware and use the webpack.config.js 11 | // configuration file as a base. 12 | app.use( 13 | webpackDevMiddleware( 14 | compiler, { 15 | publicPath: config.output.publicPath 16 | } 17 | ), 18 | proxy( 19 | [ 20 | '!/static/rest_framework_swagger/bundles/**', 21 | ], 22 | { 23 | target: 'http://localhost:8000', // Assumes Django is running on 8000 24 | } 25 | ) 26 | ); 27 | 28 | // Serve the files on port 3000. 29 | app.listen(3000, function () { 30 | console.log('Example app listening on port 3000!\n'); 31 | }); 32 | -------------------------------------------------------------------------------- /client/styles.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | padding: 0; 4 | } 5 | 6 | .swagger-ui .topbar a { 7 | flex: none; 8 | } 9 | 10 | .swagger-ui .topbar .download-url-wrapper .download-url-button { 11 | border-radius: 4px; 12 | } 13 | 14 | .swagger-ui .user-context { 15 | font-size: 0.8rem; 16 | margin-top: 0.5rem; 17 | text-align: right; 18 | } 19 | 20 | footer.swagger-ui { 21 | box-shadow: inset 1px 2px 0 rgba(0,0,0,.15); 22 | font-size: 0.7rem; 23 | margin: 2rem 0 1rem; 24 | padding-top: 1rem; 25 | text-align: right; 26 | } 27 | -------------------------------------------------------------------------------- /client/webpack.config.js: -------------------------------------------------------------------------------- 1 | const CleanWebpackPlugin = require('clean-webpack-plugin'); 2 | const MiniCssExtractPlugin = require('mini-css-extract-plugin'); 3 | const path = require('path'); 4 | const webpack = require('webpack'); 5 | const devMode = process.env.NODE_ENV === 'dev'; 6 | 7 | const distPath = path.resolve( 8 | __dirname, 9 | '../rest_framework_swagger/static/rest_framework_swagger/bundles/' 10 | ) 11 | 12 | module.exports = { 13 | entry: { 14 | app: './index.js', 15 | }, 16 | output: { 17 | path: distPath, 18 | filename: '[name].bundle.js', 19 | publicPath: '/static/rest_framework_swagger/bundles/', 20 | }, 21 | module: { 22 | rules: [ 23 | { 24 | test: /\.css$/, 25 | use: [ 26 | MiniCssExtractPlugin.loader, 27 | 'css-loader' 28 | ] 29 | }, 30 | { 31 | test: /\.(js|jsx)$/, 32 | exclude: /node_modules/, 33 | use: { 34 | loader: 'babel-loader' 35 | } 36 | } 37 | ] 38 | }, 39 | plugins: [ 40 | new CleanWebpackPlugin( 41 | distPath, { 42 | root: path.resolve(__dirname, '../') 43 | } 44 | ), 45 | new MiniCssExtractPlugin({ 46 | filename: '[name].bundle.css', 47 | }) 48 | ], 49 | optimization: { 50 | splitChunks: { 51 | cacheGroups: { 52 | commons: { 53 | test: /[\\/]node_modules[\\/]/, 54 | name: "vendors", 55 | chunks: "all" 56 | } 57 | } 58 | } 59 | } 60 | }; 61 | -------------------------------------------------------------------------------- /docs/customization.md: -------------------------------------------------------------------------------- 1 | # Customization 2 | 3 | ## Template 4 | The template used for the SwaggerUIRenderer can be customized by overriding 5 | `rest_framework_swagger/index.html`. 6 | 7 | Here are a few basic areas which can be customized: 8 | 9 | - `{% block extra_styles %}` Add additional stylesheets 10 | - `{% block extra_scripts %}` Add additional scripts. 11 | - `{% block user_context_message %}` Customize the "Hello, user" message (Django session only) 12 | 13 | 14 | ## Version Headers 15 | See [header settings](settings.md#headers) for configuration settings. 16 | -------------------------------------------------------------------------------- /docs/img/ui-screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bestdev322/django-rest-swagger/b69bc2dd7f9193fa5a8c7d130d5d0fd0f8538292/docs/img/ui-screenshot.png -------------------------------------------------------------------------------- /docs/index.md: -------------------------------------------------------------------------------- 1 | # Django REST Swagger 2 | Swagger/OpenAPI Documentation Generator for Django REST Framework 3 | 4 | 5 | 6 | --- 7 | 8 | **Note:** you are viewing documentation for version 2, using Django REST Framework 3.5+ and CoreAPI. Documentation for previous versions is available [here](http://django-rest-swagger.readthedocs.io/en/stable-0.3.x/). 9 | 10 | --- 11 | 12 | ## Installation 13 | 14 | `$ pip install django-rest-swagger` 15 | 16 | 17 | Add `'rest_framework_swagger'` to `INSTALLED_APPS` in Django settings. 18 | 19 | **settings.py** 20 | ```python 21 | INSTALLED_APPS = [ 22 | ... 23 | 'rest_framework_swagger', 24 | ... 25 | ] 26 | ``` 27 | 28 | ## Quick start 29 | 30 | To quickly get started, use the `get_swagger_view` shortcut. This will produce 31 | a schema view which uses common settings. For more advanced usage, please see 32 | the schemas section. 33 | 34 | #### Example 35 | 36 | **urls.py** 37 | ```python 38 | from django.conf.urls import url 39 | from rest_framework_swagger.views import get_swagger_view 40 | 41 | schema_view = get_swagger_view(title='Pastebin API') 42 | 43 | urlpatterns = [ 44 | url(r'^$', schema_view) 45 | ] 46 | ``` 47 | 48 | #### View in the browser 49 | ![Screenshot](/img/ui-screenshot.png) 50 | 51 | 52 | ## Example app 53 | An example based on the [Django REST Tutorial](http://www.django-rest-framework.org/tutorial/1-serialization/) ships with the project. It can be deployed locally using Docker, or on heroku (for free). 54 | 55 | ### Deploy with Heroku 56 | [![Deploy](https://www.herokucdn.com/deploy/button.svg)](https://heroku.com/deploy?template=https://github.com/marcgibbons/django-rest-swagger) 57 | 58 | Log in credentials are: 59 | ``` 60 | username: amy 61 | password: amy 62 | ``` 63 | 64 | ### Docker Instructions 65 | 66 | Ensure [Docker](https://www.docker.com/) is installed on your system. 67 | 68 | First, clone the repository: 69 | 70 | `$ git clone https://github.com/marcgibbons/django-rest-swagger` 71 | 72 | To quickly get up and running using the Docker image, simply run: 73 | 74 | `$ ./run_example.sh` 75 | 76 | The initial run may take several minutes to build. Once complete, the 77 | application will be available at `http://localhost:8000` 78 | 79 | Log in credentials are: 80 | ``` 81 | username: amy 82 | password: amy 83 | ``` 84 | 85 | ## Changes in 2.0 86 | Version 2.0 is fundamentally different from previous versions and leverages the new schema generation features introduced in Django REST Framework 3.4. Introspection is performed by the framework and uses CoreAPI to store definitions. This is a breaking change from previous versions which were responsible for introspection as well as overrides. 87 | 88 | New: 89 | 90 | - SwaggerUI and the OpenAPI spec are renderer classes (simpler configuration) 91 | - SwaggerUI 2.1.6 92 | - Improved performance 93 | - Allow multiple instances of Swagger UI in a single Django project 94 | - Allow rendering the OpenAPI JSON spec independently 95 | - Improved control of authentication mechanisms 96 | 97 | Deprecated: 98 | 99 | - YAML docstrings 100 | 101 | 102 | ## License 103 | ```text 104 | Copyright (c) 2013-2018, Marc Gibbons 105 | All rights reserved. 106 | 107 | Redistribution and use in source and binary forms, with or without 108 | modification, are permitted provided that the following conditions are met: 109 | 110 | 1. Redistributions of source code must retain the above copyright notice, this 111 | list of conditions and the following disclaimer. 112 | 2. Redistributions in binary form must reproduce the above copyright notice, 113 | this list of conditions and the following disclaimer in the documentation 114 | and/or other materials provided with the distribution. 115 | 116 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 117 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 118 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 119 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 120 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 121 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 122 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 123 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 124 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 125 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 126 | ``` 127 | -------------------------------------------------------------------------------- /docs/schema.md: -------------------------------------------------------------------------------- 1 | # Rendering the Schema 2 | 3 | Django REST Swagger includes two renderers; the `OpenAPIRenderer` and the 4 | `SwaggerUIRenderer`. 5 | 6 | The `OpenAPIRenderer` is responsible for generating the JSON spec, while the `SwaggerUIRenderer` renders the UI (HTML/JS/CSS). 7 | 8 | **Note:** to render the UI, both renderers must be included. The `OpenAPIRenderer` may be used on its own if you wish to host the UI independently. 9 | 10 | 11 | ### The `get_swagger_view` shortcut 12 | 13 | As a convenience, a shortcut method with sensible default configurations is provided to generate SwaggerUI documentation for your API. This view features the following: 14 | 15 | - Enforces the DRF permission classes and user context. This means that anonymous users may not see the full endpoint list should views require authentication. 16 | - Anyone can view the docs, however, documentation will only be generated for endpoints which are publicly available. 17 | - Renders CoreJSON 18 | 19 | Parameters: 20 | 21 | `title`: The title of the documentation (Default: `None`) 22 | 23 | `url`: The URL to the documentation (if not on the same host or path). Can be a relative path or can be an absolute URL. (Default: `None`) 24 | 25 | 26 | #### Example: 27 | ```python 28 | from rest_framework_swagger.views import get_swagger_view 29 | 30 | schema_view = get_swagger_view(title='My great API', url='/a-different-path') 31 | ``` 32 | 33 | ### Advanced Usage 34 | 35 | For finer control of the documentation, create your own schema view by using a function based or class-based view. This can be useful if you want to produce documentation for specific URL patterns, or URL confs. 36 | 37 | For more detailed documentation on the schema generator, see: 38 | 39 | [http://www.django-rest-framework.org/api-guide/schemas/](http://www.django-rest-framework.org/api-guide/schemas/#schemagenerator) 40 | 41 | 42 | Example: Class-based view 43 | ```python 44 | from rest_framework.permissions import AllowAny 45 | from rest_framework.response import Response 46 | from rest_framework.schemas import SchemaGenerator 47 | from rest_framework.views import APIView 48 | from rest_framework_swagger import renderers 49 | 50 | 51 | class SwaggerSchemaView(APIView): 52 | permission_classes = [AllowAny] 53 | renderer_classes = [ 54 | renderers.OpenAPIRenderer, 55 | renderers.SwaggerUIRenderer 56 | ] 57 | 58 | def get(self, request): 59 | generator = SchemaGenerator() 60 | schema = generator.get_schema(request=request) 61 | 62 | return Response(schema) 63 | ``` 64 | 65 | 66 | Example: function based view 67 | ```python 68 | from rest_framework_swagger.renderers import OpenAPIRenderer, SwaggerUIRenderer 69 | from rest_framework.decorators import api_view, renderer_classes 70 | from rest_framework import response, schemas 71 | 72 | @api_view() 73 | @renderer_classes([SwaggerUIRenderer, OpenAPIRenderer]) 74 | def schema_view(request): 75 | generator = schemas.SchemaGenerator(title='Pastebin API') 76 | return response.Response(generator.get_schema(request=request)) 77 | ``` 78 | -------------------------------------------------------------------------------- /docs/settings.md: -------------------------------------------------------------------------------- 1 | # Settings 2 | The configuration of Django REST Swagger is identical to Django REST Framework. Settings are configurable in `settings.py` by defining `SWAGGER_SETTINGS`. 3 | 4 | Example: 5 | 6 | **settings.py** 7 | ```python 8 | SWAGGER_SETTINGS = { 9 | 'SECURITY_DEFINITIONS': { 10 | 'basic': { 11 | 'type': 'basic' 12 | } 13 | }, 14 | ... 15 | } 16 | ``` 17 | 18 | ## Authentication 19 | ### USE_SESSION_AUTH 20 | Toggles the use of Django Auth as an authentication mechanism. Setting it to `True` will display 21 | a login/logout button on the Swagger UI and post csrf_tokens to the API. 22 | 23 | **Default:** `True` 24 | 25 | 26 | **Note:** The login/logout button relies on the `LOGIN_URL` and `LOGOUT_URL` settings which default to `/accounts/login`. These can either be configured under `SWAGGER_SETTINGS` or Django settings. 27 | 28 | **urls.py** 29 | ```python 30 | urlpatterns = [ 31 | url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')) 32 | ] 33 | ``` 34 | **settings.py** 35 | ```python 36 | LOGIN_URL = 'rest_framework:login' 37 | LOGOUT_URL = 'rest_framework:logout' 38 | ``` 39 | 40 | ### LOGIN_URL 41 | The URL to use to log in session authentication. Accepts named URL patterns. 42 | 43 | **Default:** `django.conf.settings.LOGIN_URL` 44 | 45 | 46 | ### LOGOUT_URL 47 | The URL to use to log out of session authentication. Accepts named URL patterns. 48 | 49 | **Default:** `django.conf.settings.LOGOUT_URL` 50 | 51 | 52 | ### SECURITY_DEFINITIONS 53 | The security definitions configures which authentication methods can be used by Swagger. The schemes types currently supported by the OpenAPI 2.0 spec are `basic`, `apiKey` and `oauth2`. 54 | 55 | For more information on available options, please consult the OpenAPI [Security Object Definition](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#security-definitions-object). 56 | 57 | **Default:** 58 | ```python 59 | { 60 | 'basic': { 61 | 'type': 'basic' 62 | } 63 | } 64 | ``` 65 | 66 | ## Headers 67 | ### ACCEPT_HEADER_VERSION 68 | Use this setting if you are using the `AcceptHeaderVersioning` version scheme 69 | and require a value to interact with the API. 70 | 71 | **Default**: `None` 72 | 73 | E.g.: Setting to `1.0` will modify the HTTP Accept header from 74 | `application/json` to `application/json; version=1.0`. 75 | 76 | For further customization, use the `CUSTOM_HEADERS`. 77 | 78 | #### CUSTOM_HEADERS 79 | Define a dictionary of values to be passed as HTTP headers in all API requests. 80 | 81 | **Default**: `{}` 82 | 83 | All key/val provided in this dictionary will be set on the request headers for 84 | all API requests. 85 | 86 | ## SwaggerUI Settings 87 | Below are some basic configuration settings for SwaggerUI. Note that for more advanced use cases, you may wish to write your own `rest_framework_swagger/static/init.js` file. 88 | 89 | ### APIS_SORTER 90 | Set to `alpha` to enable alphabetical sorting. 91 | 92 | **Default:** `None` 93 | 94 | ### DOC_EXPANSION 95 | Controls how the API listing is displayed. It can be set to: 96 | 97 | - `None`: All operations are collapsed 98 | - `"list"`: Lists all the operations 99 | - `"full"`: Expands all the operations 100 | 101 | **Default:** `None` 102 | 103 | ### JSON_EDITOR 104 | Enables a graphical view for editing complex bodies. 105 | 106 | **Default:** `False` 107 | 108 | ### OPERATIONS_SORTER 109 | Sorts the operation list of each API. It can be set to: 110 | 111 | - `alpha`: Sort alphabetically 112 | - `method`: Sort by HTTP method 113 | 114 | **Default:** `None` 115 | 116 | ### SHOW_REQUEST_HEADERS 117 | Set to `True` to display the request headers. 118 | 119 | **Default:** `False` 120 | 121 | ### SUPPORTED_SUBMIT_METHODS 122 | A list of HTTP methods can be interacted with using the "Try it out!" button. 123 | 124 | **Default:** `['get', 'post', 'put', 'delete', 'patch']` 125 | 126 | 127 | ### VALIDATOR_URL 128 | URL to swagger.io's online schema validator. Can be modified to point to a local 129 | install, or set to `None` to disable. 130 | 131 | **Default:** `https://online.swagger.io/validator/` 132 | -------------------------------------------------------------------------------- /example_app/README.md: -------------------------------------------------------------------------------- 1 | # Example app 2 | This module was copied from https://github.com/tomchristie/rest-framework-tutorial 3 | 4 | # REST framework tutorial 5 | 6 | Source code for the [Django REST framework tutorial][tut]. 7 | 8 | [tut]: http://tomchristie.github.com/django-rest-framework/tutorial/1-serialization 9 | -------------------------------------------------------------------------------- /example_app/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bestdev322/django-rest-swagger/b69bc2dd7f9193fa5a8c7d130d5d0fd0f8538292/example_app/__init__.py -------------------------------------------------------------------------------- /example_app/manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import os 3 | import sys 4 | 5 | if __name__ == "__main__": 6 | sys.path.append(os.path.abspath(os.path.dirname('../%s' % __file__))) 7 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "tutorial.settings") 8 | 9 | from django.core.management import execute_from_command_line 10 | 11 | execute_from_command_line(sys.argv) 12 | -------------------------------------------------------------------------------- /example_app/snippets/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bestdev322/django-rest-swagger/b69bc2dd7f9193fa5a8c7d130d5d0fd0f8538292/example_app/snippets/__init__.py -------------------------------------------------------------------------------- /example_app/snippets/fixtures/users.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "pk": 2, 4 | "model": "auth.user", 5 | "fields": { 6 | "username": "aziz", 7 | "first_name": "", 8 | "last_name": "", 9 | "is_active": true, 10 | "is_superuser": false, 11 | "is_staff": false, 12 | "last_login": "2012-10-28T21:36:57.799Z", 13 | "groups": [], 14 | "user_permissions": [], 15 | "password": "pbkdf2_sha256$10000$2x3LOiFCb9sq$3jiN4zgb3wYHQ9fpn/elUrcn1S1Bq/q0djZFBjb8Y2w=", 16 | "email": "", 17 | "date_joined": "2012-10-28T21:36:57.799Z" 18 | } 19 | }, 20 | { 21 | "pk": 3, 22 | "model": "auth.user", 23 | "fields": { 24 | "username": "amy", 25 | "first_name": "", 26 | "last_name": "", 27 | "is_active": true, 28 | "is_superuser": false, 29 | "is_staff": false, 30 | "last_login": "2012-10-28T21:42:34.081Z", 31 | "groups": [], 32 | "user_permissions": [], 33 | "password": "pbkdf2_sha256$10000$wjy2WvTgw1Ro$oR8pVFHIBqZUmD9XEHdRl5m4TxWOF+qnvZn/q+npTlc=", 34 | "email": "", 35 | "date_joined": "2012-10-28T21:42:34.081Z" 36 | } 37 | }, 38 | { 39 | "pk": 4, 40 | "model": "auth.user", 41 | "fields": { 42 | "username": "max", 43 | "first_name": "", 44 | "last_name": "", 45 | "is_active": true, 46 | "is_superuser": false, 47 | "is_staff": false, 48 | "last_login": "2012-10-28T21:42:45.711Z", 49 | "groups": [], 50 | "user_permissions": [], 51 | "password": "pbkdf2_sha256$10000$NhDNt8GNYfjC$0FlcsJxt8Sac0dvGv+xcaUVSUfh1UYZfWEq3C1WoHjc=", 52 | "email": "", 53 | "date_joined": "2012-10-28T21:42:45.711Z" 54 | } 55 | }, 56 | { 57 | "pk": 5, 58 | "model": "auth.user", 59 | "fields": { 60 | "username": "jose", 61 | "first_name": "", 62 | "last_name": "", 63 | "is_active": true, 64 | "is_superuser": false, 65 | "is_staff": false, 66 | "last_login": "2012-10-28T21:43:03.591Z", 67 | "groups": [], 68 | "user_permissions": [], 69 | "password": "pbkdf2_sha256$10000$ibnHXtPQKwBN$Kab9tTROT6bpxnAI1imgb0kdlAmBuAQ5Z0fAzHbkL68=", 70 | "email": "", 71 | "date_joined": "2012-10-28T21:43:03.591Z" 72 | } 73 | } 74 | ] 75 | -------------------------------------------------------------------------------- /example_app/snippets/migrations/0001_initial.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by Django 1.9.7 on 2016-07-09 18:40 3 | from __future__ import unicode_literals 4 | 5 | from django.conf import settings 6 | from django.db import migrations, models 7 | import django.db.models.deletion 8 | 9 | 10 | class Migration(migrations.Migration): 11 | 12 | initial = True 13 | 14 | dependencies = [ 15 | migrations.swappable_dependency(settings.AUTH_USER_MODEL), 16 | ] 17 | 18 | operations = [ 19 | migrations.CreateModel( 20 | name='Snippet', 21 | fields=[ 22 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 23 | ('created', models.DateTimeField(auto_now_add=True)), 24 | ('title', models.CharField(blank=True, default='', max_length=100)), 25 | ('code', models.TextField()), 26 | ('linenos', models.BooleanField(default=False)), 27 | ('language', models.CharField(choices=[('abap', 'ABAP'), ('ada', 'Ada'), ('agda', 'Agda'), ('ahk', 'autohotkey'), ('alloy', 'Alloy'), ('antlr', 'ANTLR'), ('antlr-as', 'ANTLR With ActionScript Target'), ('antlr-cpp', 'ANTLR With CPP Target'), ('antlr-csharp', 'ANTLR With C# Target'), ('antlr-java', 'ANTLR With Java Target'), ('antlr-objc', 'ANTLR With ObjectiveC Target'), ('antlr-perl', 'ANTLR With Perl Target'), ('antlr-python', 'ANTLR With Python Target'), ('antlr-ruby', 'ANTLR With Ruby Target'), ('apacheconf', 'ApacheConf'), ('apl', 'APL'), ('applescript', 'AppleScript'), ('as', 'ActionScript'), ('as3', 'ActionScript 3'), ('aspectj', 'AspectJ'), ('aspx-cs', 'aspx-cs'), ('aspx-vb', 'aspx-vb'), ('asy', 'Asymptote'), ('at', 'AmbientTalk'), ('autoit', 'AutoIt'), ('awk', 'Awk'), ('basemake', 'Base Makefile'), ('bash', 'Bash'), ('bat', 'Batchfile'), ('bbcode', 'BBCode'), ('befunge', 'Befunge'), ('blitzbasic', 'BlitzBasic'), ('blitzmax', 'BlitzMax'), ('boo', 'Boo'), ('brainfuck', 'Brainfuck'), ('bro', 'Bro'), ('bugs', 'BUGS'), ('c', 'C'), ('c-objdump', 'c-objdump'), ('ca65', 'ca65 assembler'), ('cbmbas', 'CBM BASIC V2'), ('ceylon', 'Ceylon'), ('cfc', 'Coldfusion CFC'), ('cfengine3', 'CFEngine3'), ('cfm', 'Coldfusion HTML'), ('cfs', 'cfstatement'), ('chai', 'ChaiScript'), ('chapel', 'Chapel'), ('cheetah', 'Cheetah'), ('cirru', 'Cirru'), ('clay', 'Clay'), ('clojure', 'Clojure'), ('clojurescript', 'ClojureScript'), ('cmake', 'CMake'), ('cobol', 'COBOL'), ('cobolfree', 'COBOLFree'), ('coffee-script', 'CoffeeScript'), ('common-lisp', 'Common Lisp'), ('console', 'Bash Session'), ('control', 'Debian Control file'), ('coq', 'Coq'), ('cpp', 'C++'), ('cpp-objdump', 'cpp-objdump'), ('croc', 'Croc'), ('cryptol', 'Cryptol'), ('csharp', 'C#'), ('css', 'CSS'), ('css+django', 'CSS+Django/Jinja'), ('css+erb', 'CSS+Ruby'), ('css+genshitext', 'CSS+Genshi Text'), ('css+lasso', 'CSS+Lasso'), ('css+mako', 'CSS+Mako'), ('css+mozpreproc', 'CSS+mozpreproc'), ('css+myghty', 'CSS+Myghty'), ('css+php', 'CSS+PHP'), ('css+smarty', 'CSS+Smarty'), ('cucumber', 'Gherkin'), ('cuda', 'CUDA'), ('cypher', 'Cypher'), ('cython', 'Cython'), ('d', 'D'), ('d-objdump', 'd-objdump'), ('dart', 'Dart'), ('delphi', 'Delphi'), ('dg', 'dg'), ('diff', 'Diff'), ('django', 'Django/Jinja'), ('docker', 'Docker'), ('dpatch', 'Darcs Patch'), ('dtd', 'DTD'), ('duel', 'Duel'), ('dylan', 'Dylan'), ('dylan-console', 'Dylan session'), ('dylan-lid', 'DylanLID'), ('ebnf', 'EBNF'), ('ec', 'eC'), ('ecl', 'ECL'), ('eiffel', 'Eiffel'), ('elixir', 'Elixir'), ('erb', 'ERB'), ('erl', 'Erlang erl session'), ('erlang', 'Erlang'), ('evoque', 'Evoque'), ('factor', 'Factor'), ('fan', 'Fantom'), ('fancy', 'Fancy'), ('felix', 'Felix'), ('fortran', 'Fortran'), ('foxpro', 'FoxPro'), ('fsharp', 'FSharp'), ('gap', 'GAP'), ('gas', 'GAS'), ('genshi', 'Genshi'), ('genshitext', 'Genshi Text'), ('glsl', 'GLSL'), ('gnuplot', 'Gnuplot'), ('go', 'Go'), ('golo', 'Golo'), ('gooddata-cl', 'GoodData-CL'), ('gosu', 'Gosu'), ('groff', 'Groff'), ('groovy', 'Groovy'), ('gst', 'Gosu Template'), ('haml', 'Haml'), ('handlebars', 'Handlebars'), ('haskell', 'Haskell'), ('haxeml', 'Hxml'), ('html', 'HTML'), ('html+cheetah', 'HTML+Cheetah'), ('html+django', 'HTML+Django/Jinja'), ('html+evoque', 'HTML+Evoque'), ('html+genshi', 'HTML+Genshi'), ('html+handlebars', 'HTML+Handlebars'), ('html+lasso', 'HTML+Lasso'), ('html+mako', 'HTML+Mako'), ('html+myghty', 'HTML+Myghty'), ('html+php', 'HTML+PHP'), ('html+smarty', 'HTML+Smarty'), ('html+twig', 'HTML+Twig'), ('html+velocity', 'HTML+Velocity'), ('http', 'HTTP'), ('hx', 'Haxe'), ('hybris', 'Hybris'), ('hylang', 'Hy'), ('i6t', 'Inform 6 template'), ('idl', 'IDL'), ('idris', 'Idris'), ('iex', 'Elixir iex session'), ('igor', 'Igor'), ('inform6', 'Inform 6'), ('inform7', 'Inform 7'), ('ini', 'INI'), ('io', 'Io'), ('ioke', 'Ioke'), ('irc', 'IRC logs'), ('isabelle', 'Isabelle'), ('jade', 'Jade'), ('jags', 'JAGS'), ('jasmin', 'Jasmin'), ('java', 'Java'), ('javascript+mozpreproc', 'Javascript+mozpreproc'), ('jlcon', 'Julia console'), ('js', 'JavaScript'), ('js+cheetah', 'JavaScript+Cheetah'), ('js+django', 'JavaScript+Django/Jinja'), ('js+erb', 'JavaScript+Ruby'), ('js+genshitext', 'JavaScript+Genshi Text'), ('js+lasso', 'JavaScript+Lasso'), ('js+mako', 'JavaScript+Mako'), ('js+myghty', 'JavaScript+Myghty'), ('js+php', 'JavaScript+PHP'), ('js+smarty', 'JavaScript+Smarty'), ('json', 'JSON'), ('jsonld', 'JSON-LD'), ('jsp', 'Java Server Page'), ('julia', 'Julia'), ('kal', 'Kal'), ('kconfig', 'Kconfig'), ('koka', 'Koka'), ('kotlin', 'Kotlin'), ('lagda', 'Literate Agda'), ('lasso', 'Lasso'), ('lcry', 'Literate Cryptol'), ('lean', 'Lean'), ('lhs', 'Literate Haskell'), ('lidr', 'Literate Idris'), ('lighty', 'Lighttpd configuration file'), ('limbo', 'Limbo'), ('liquid', 'liquid'), ('live-script', 'LiveScript'), ('llvm', 'LLVM'), ('logos', 'Logos'), ('logtalk', 'Logtalk'), ('lsl', 'LSL'), ('lua', 'Lua'), ('make', 'Makefile'), ('mako', 'Mako'), ('maql', 'MAQL'), ('mask', 'Mask'), ('mason', 'Mason'), ('mathematica', 'Mathematica'), ('matlab', 'Matlab'), ('matlabsession', 'Matlab session'), ('minid', 'MiniD'), ('modelica', 'Modelica'), ('modula2', 'Modula-2'), ('monkey', 'Monkey'), ('moocode', 'MOOCode'), ('moon', 'MoonScript'), ('mozhashpreproc', 'mozhashpreproc'), ('mozpercentpreproc', 'mozpercentpreproc'), ('mql', 'MQL'), ('mscgen', 'Mscgen'), ('mupad', 'MuPAD'), ('mxml', 'MXML'), ('myghty', 'Myghty'), ('mysql', 'MySQL'), ('nasm', 'NASM'), ('nemerle', 'Nemerle'), ('nesc', 'nesC'), ('newlisp', 'NewLisp'), ('newspeak', 'Newspeak'), ('nginx', 'Nginx configuration file'), ('nimrod', 'Nimrod'), ('nit', 'Nit'), ('nixos', 'Nix'), ('nsis', 'NSIS'), ('numpy', 'NumPy'), ('objdump', 'objdump'), ('objdump-nasm', 'objdump-nasm'), ('objective-c', 'Objective-C'), ('objective-c++', 'Objective-C++'), ('objective-j', 'Objective-J'), ('ocaml', 'OCaml'), ('octave', 'Octave'), ('ooc', 'Ooc'), ('opa', 'Opa'), ('openedge', 'OpenEdge ABL'), ('pan', 'Pan'), ('pawn', 'Pawn'), ('perl', 'Perl'), ('perl6', 'Perl6'), ('php', 'PHP'), ('pig', 'Pig'), ('pike', 'Pike'), ('plpgsql', 'PL/pgSQL'), ('postgresql', 'PostgreSQL SQL dialect'), ('postscript', 'PostScript'), ('pot', 'Gettext Catalog'), ('pov', 'POVRay'), ('powershell', 'PowerShell'), ('prolog', 'Prolog'), ('properties', 'Properties'), ('protobuf', 'Protocol Buffer'), ('psql', 'PostgreSQL console (psql)'), ('puppet', 'Puppet'), ('py3tb', 'Python 3.0 Traceback'), ('pycon', 'Python console session'), ('pypylog', 'PyPy Log'), ('pytb', 'Python Traceback'), ('python', 'Python'), ('python3', 'Python 3'), ('qbasic', 'QBasic'), ('qml', 'QML'), ('racket', 'Racket'), ('ragel', 'Ragel'), ('ragel-c', 'Ragel in C Host'), ('ragel-cpp', 'Ragel in CPP Host'), ('ragel-d', 'Ragel in D Host'), ('ragel-em', 'Embedded Ragel'), ('ragel-java', 'Ragel in Java Host'), ('ragel-objc', 'Ragel in Objective C Host'), ('ragel-ruby', 'Ragel in Ruby Host'), ('raw', 'Raw token data'), ('rb', 'Ruby'), ('rbcon', 'Ruby irb session'), ('rconsole', 'RConsole'), ('rd', 'Rd'), ('rebol', 'REBOL'), ('red', 'Red'), ('redcode', 'Redcode'), ('registry', 'reg'), ('resource', 'ResourceBundle'), ('rexx', 'Rexx'), ('rhtml', 'RHTML'), ('robotframework', 'RobotFramework'), ('rql', 'RQL'), ('rsl', 'RSL'), ('rst', 'reStructuredText'), ('rust', 'Rust'), ('sass', 'Sass'), ('scala', 'Scala'), ('scaml', 'Scaml'), ('scheme', 'Scheme'), ('scilab', 'Scilab'), ('scss', 'SCSS'), ('shell-session', 'Shell Session'), ('slim', 'Slim'), ('smali', 'Smali'), ('smalltalk', 'Smalltalk'), ('smarty', 'Smarty'), ('sml', 'Standard ML'), ('snobol', 'Snobol'), ('sourceslist', 'Debian Sourcelist'), ('sp', 'SourcePawn'), ('sparql', 'SPARQL'), ('spec', 'RPMSpec'), ('splus', 'S'), ('sql', 'SQL'), ('sqlite3', 'sqlite3con'), ('squidconf', 'SquidConf'), ('ssp', 'Scalate Server Page'), ('stan', 'Stan'), ('swift', 'Swift'), ('swig', 'SWIG'), ('systemverilog', 'systemverilog'), ('tads3', 'TADS 3'), ('tcl', 'Tcl'), ('tcsh', 'Tcsh'), ('tea', 'Tea'), ('tex', 'TeX'), ('text', 'Text only'), ('todotxt', 'Todotxt'), ('trac-wiki', 'MoinMoin/Trac Wiki markup'), ('treetop', 'Treetop'), ('ts', 'TypeScript'), ('twig', 'Twig'), ('urbiscript', 'UrbiScript'), ('vala', 'Vala'), ('vb.net', 'VB.net'), ('vctreestatus', 'VCTreeStatus'), ('velocity', 'Velocity'), ('verilog', 'verilog'), ('vgl', 'VGL'), ('vhdl', 'vhdl'), ('vim', 'VimL'), ('xml', 'XML'), ('xml+cheetah', 'XML+Cheetah'), ('xml+django', 'XML+Django/Jinja'), ('xml+erb', 'XML+Ruby'), ('xml+evoque', 'XML+Evoque'), ('xml+lasso', 'XML+Lasso'), ('xml+mako', 'XML+Mako'), ('xml+myghty', 'XML+Myghty'), ('xml+php', 'XML+PHP'), ('xml+smarty', 'XML+Smarty'), ('xml+velocity', 'XML+Velocity'), ('xquery', 'XQuery'), ('xslt', 'XSLT'), ('xtend', 'Xtend'), ('xul+mozpreproc', 'XUL+mozpreproc'), ('yaml', 'YAML'), ('yaml+jinja', 'YAML+Jinja'), ('zephir', 'Zephir')], default='python', max_length=100)), 28 | ('style', models.CharField(choices=[('autumn', 'autumn'), ('borland', 'borland'), ('bw', 'bw'), ('colorful', 'colorful'), ('default', 'default'), ('emacs', 'emacs'), ('friendly', 'friendly'), ('fruity', 'fruity'), ('igor', 'igor'), ('manni', 'manni'), ('monokai', 'monokai'), ('murphy', 'murphy'), ('native', 'native'), ('paraiso-dark', 'paraiso-dark'), ('paraiso-light', 'paraiso-light'), ('pastie', 'pastie'), ('perldoc', 'perldoc'), ('rrt', 'rrt'), ('tango', 'tango'), ('trac', 'trac'), ('vim', 'vim'), ('vs', 'vs'), ('xcode', 'xcode')], default='friendly', max_length=100)), 29 | ('highlighted', models.TextField()), 30 | ('owner', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='snippets', to=settings.AUTH_USER_MODEL)), 31 | ], 32 | options={ 33 | 'ordering': ('created',), 34 | }, 35 | ), 36 | ] 37 | -------------------------------------------------------------------------------- /example_app/snippets/migrations/0002_auto_20160717_2140.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by Django 1.9.7 on 2016-07-18 02:40 3 | from __future__ import unicode_literals 4 | 5 | from django.db import migrations, models 6 | 7 | 8 | class Migration(migrations.Migration): 9 | 10 | dependencies = [ 11 | ('snippets', '0001_initial'), 12 | ] 13 | 14 | operations = [ 15 | migrations.AlterField( 16 | model_name='snippet', 17 | name='language', 18 | field=models.CharField(choices=[('abap', 'ABAP'), ('ada', 'Ada'), ('agda', 'Agda'), ('ahk', 'autohotkey'), ('alloy', 'Alloy'), ('antlr', 'ANTLR'), ('antlr-as', 'ANTLR With ActionScript Target'), ('antlr-cpp', 'ANTLR With CPP Target'), ('antlr-csharp', 'ANTLR With C# Target'), ('antlr-java', 'ANTLR With Java Target'), ('antlr-objc', 'ANTLR With ObjectiveC Target'), ('antlr-perl', 'ANTLR With Perl Target'), ('antlr-python', 'ANTLR With Python Target'), ('antlr-ruby', 'ANTLR With Ruby Target'), ('apacheconf', 'ApacheConf'), ('apl', 'APL'), ('applescript', 'AppleScript'), ('as', 'ActionScript'), ('as3', 'ActionScript 3'), ('aspectj', 'AspectJ'), ('aspx-cs', 'aspx-cs'), ('aspx-vb', 'aspx-vb'), ('asy', 'Asymptote'), ('at', 'AmbientTalk'), ('autoit', 'AutoIt'), ('awk', 'Awk'), ('basemake', 'Base Makefile'), ('bash', 'Bash'), ('bat', 'Batchfile'), ('bbcode', 'BBCode'), ('befunge', 'Befunge'), ('blitzbasic', 'BlitzBasic'), ('blitzmax', 'BlitzMax'), ('boo', 'Boo'), ('brainfuck', 'Brainfuck'), ('bro', 'Bro'), ('bugs', 'BUGS'), ('c', 'C'), ('c-objdump', 'c-objdump'), ('ca65', 'ca65 assembler'), ('cbmbas', 'CBM BASIC V2'), ('ceylon', 'Ceylon'), ('cfc', 'Coldfusion CFC'), ('cfengine3', 'CFEngine3'), ('cfm', 'Coldfusion HTML'), ('cfs', 'cfstatement'), ('chai', 'ChaiScript'), ('chapel', 'Chapel'), ('cheetah', 'Cheetah'), ('cirru', 'Cirru'), ('clay', 'Clay'), ('clojure', 'Clojure'), ('clojurescript', 'ClojureScript'), ('cmake', 'CMake'), ('cobol', 'COBOL'), ('cobolfree', 'COBOLFree'), ('coffee-script', 'CoffeeScript'), ('common-lisp', 'Common Lisp'), ('console', 'Bash Session'), ('control', 'Debian Control file'), ('coq', 'Coq'), ('cpp', 'C++'), ('cpp-objdump', 'cpp-objdump'), ('croc', 'Croc'), ('cryptol', 'Cryptol'), ('csharp', 'C#'), ('css', 'CSS'), ('css+django', 'CSS+Django/Jinja'), ('css+erb', 'CSS+Ruby'), ('css+genshitext', 'CSS+Genshi Text'), ('css+lasso', 'CSS+Lasso'), ('css+mako', 'CSS+Mako'), ('css+mozpreproc', 'CSS+mozpreproc'), ('css+myghty', 'CSS+Myghty'), ('css+php', 'CSS+PHP'), ('css+smarty', 'CSS+Smarty'), ('cucumber', 'Gherkin'), ('cuda', 'CUDA'), ('cypher', 'Cypher'), ('cython', 'Cython'), ('d', 'D'), ('d-objdump', 'd-objdump'), ('dart', 'Dart'), ('delphi', 'Delphi'), ('dg', 'dg'), ('diff', 'Diff'), ('django', 'Django/Jinja'), ('docker', 'Docker'), ('dpatch', 'Darcs Patch'), ('dtd', 'DTD'), ('duel', 'Duel'), ('dylan', 'Dylan'), ('dylan-console', 'Dylan session'), ('dylan-lid', 'DylanLID'), ('ebnf', 'EBNF'), ('ec', 'eC'), ('ecl', 'ECL'), ('eiffel', 'Eiffel'), ('elixir', 'Elixir'), ('erb', 'ERB'), ('erl', 'Erlang erl session'), ('erlang', 'Erlang'), ('evoque', 'Evoque'), ('factor', 'Factor'), ('fan', 'Fantom'), ('fancy', 'Fancy'), ('felix', 'Felix'), ('fortran', 'Fortran'), ('foxpro', 'FoxPro'), ('fsharp', 'FSharp'), ('gap', 'GAP'), ('gas', 'GAS'), ('genshi', 'Genshi'), ('genshitext', 'Genshi Text'), ('glsl', 'GLSL'), ('gnuplot', 'Gnuplot'), ('go', 'Go'), ('golo', 'Golo'), ('gooddata-cl', 'GoodData-CL'), ('gosu', 'Gosu'), ('groff', 'Groff'), ('groovy', 'Groovy'), ('gst', 'Gosu Template'), ('haml', 'Haml'), ('handlebars', 'Handlebars'), ('haskell', 'Haskell'), ('haxeml', 'Hxml'), ('html', 'HTML'), ('html+cheetah', 'HTML+Cheetah'), ('html+django', 'HTML+Django/Jinja'), ('html+evoque', 'HTML+Evoque'), ('html+genshi', 'HTML+Genshi'), ('html+handlebars', 'HTML+Handlebars'), ('html+lasso', 'HTML+Lasso'), ('html+mako', 'HTML+Mako'), ('html+myghty', 'HTML+Myghty'), ('html+php', 'HTML+PHP'), ('html+smarty', 'HTML+Smarty'), ('html+twig', 'HTML+Twig'), ('html+velocity', 'HTML+Velocity'), ('http', 'HTTP'), ('hx', 'Haxe'), ('hybris', 'Hybris'), ('hylang', 'Hy'), ('i6t', 'Inform 6 template'), ('idl', 'IDL'), ('idris', 'Idris'), ('iex', 'Elixir iex session'), ('igor', 'Igor'), ('inform6', 'Inform 6'), ('inform7', 'Inform 7'), ('ini', 'INI'), ('io', 'Io'), ('ioke', 'Ioke'), ('ipython2', 'IPython'), ('ipython3', 'IPython3'), ('ipythonconsole', 'IPython console session'), ('irc', 'IRC logs'), ('isabelle', 'Isabelle'), ('jade', 'Jade'), ('jags', 'JAGS'), ('jasmin', 'Jasmin'), ('java', 'Java'), ('javascript+mozpreproc', 'Javascript+mozpreproc'), ('jlcon', 'Julia console'), ('js', 'JavaScript'), ('js+cheetah', 'JavaScript+Cheetah'), ('js+django', 'JavaScript+Django/Jinja'), ('js+erb', 'JavaScript+Ruby'), ('js+genshitext', 'JavaScript+Genshi Text'), ('js+lasso', 'JavaScript+Lasso'), ('js+mako', 'JavaScript+Mako'), ('js+myghty', 'JavaScript+Myghty'), ('js+php', 'JavaScript+PHP'), ('js+smarty', 'JavaScript+Smarty'), ('json', 'JSON'), ('jsonld', 'JSON-LD'), ('jsp', 'Java Server Page'), ('julia', 'Julia'), ('kal', 'Kal'), ('kconfig', 'Kconfig'), ('koka', 'Koka'), ('kotlin', 'Kotlin'), ('lagda', 'Literate Agda'), ('lasso', 'Lasso'), ('lcry', 'Literate Cryptol'), ('lean', 'Lean'), ('lhs', 'Literate Haskell'), ('lidr', 'Literate Idris'), ('lighty', 'Lighttpd configuration file'), ('limbo', 'Limbo'), ('liquid', 'liquid'), ('live-script', 'LiveScript'), ('llvm', 'LLVM'), ('logos', 'Logos'), ('logtalk', 'Logtalk'), ('lsl', 'LSL'), ('lua', 'Lua'), ('make', 'Makefile'), ('mako', 'Mako'), ('maql', 'MAQL'), ('mask', 'Mask'), ('mason', 'Mason'), ('mathematica', 'Mathematica'), ('matlab', 'Matlab'), ('matlabsession', 'Matlab session'), ('minid', 'MiniD'), ('modelica', 'Modelica'), ('modula2', 'Modula-2'), ('monkey', 'Monkey'), ('moocode', 'MOOCode'), ('moon', 'MoonScript'), ('mozhashpreproc', 'mozhashpreproc'), ('mozpercentpreproc', 'mozpercentpreproc'), ('mql', 'MQL'), ('mscgen', 'Mscgen'), ('mupad', 'MuPAD'), ('mxml', 'MXML'), ('myghty', 'Myghty'), ('mysql', 'MySQL'), ('nasm', 'NASM'), ('nemerle', 'Nemerle'), ('nesc', 'nesC'), ('newlisp', 'NewLisp'), ('newspeak', 'Newspeak'), ('nginx', 'Nginx configuration file'), ('nimrod', 'Nimrod'), ('nit', 'Nit'), ('nixos', 'Nix'), ('nsis', 'NSIS'), ('numpy', 'NumPy'), ('objdump', 'objdump'), ('objdump-nasm', 'objdump-nasm'), ('objective-c', 'Objective-C'), ('objective-c++', 'Objective-C++'), ('objective-j', 'Objective-J'), ('ocaml', 'OCaml'), ('octave', 'Octave'), ('ooc', 'Ooc'), ('opa', 'Opa'), ('openedge', 'OpenEdge ABL'), ('pan', 'Pan'), ('pawn', 'Pawn'), ('perl', 'Perl'), ('perl6', 'Perl6'), ('php', 'PHP'), ('pig', 'Pig'), ('pike', 'Pike'), ('plpgsql', 'PL/pgSQL'), ('postgresql', 'PostgreSQL SQL dialect'), ('postscript', 'PostScript'), ('pot', 'Gettext Catalog'), ('pov', 'POVRay'), ('powershell', 'PowerShell'), ('prolog', 'Prolog'), ('properties', 'Properties'), ('protobuf', 'Protocol Buffer'), ('psql', 'PostgreSQL console (psql)'), ('puppet', 'Puppet'), ('py3tb', 'Python 3.0 Traceback'), ('pycon', 'Python console session'), ('pypylog', 'PyPy Log'), ('pytb', 'Python Traceback'), ('python', 'Python'), ('python3', 'Python 3'), ('qbasic', 'QBasic'), ('qml', 'QML'), ('racket', 'Racket'), ('ragel', 'Ragel'), ('ragel-c', 'Ragel in C Host'), ('ragel-cpp', 'Ragel in CPP Host'), ('ragel-d', 'Ragel in D Host'), ('ragel-em', 'Embedded Ragel'), ('ragel-java', 'Ragel in Java Host'), ('ragel-objc', 'Ragel in Objective C Host'), ('ragel-ruby', 'Ragel in Ruby Host'), ('raw', 'Raw token data'), ('rb', 'Ruby'), ('rbcon', 'Ruby irb session'), ('rconsole', 'RConsole'), ('rd', 'Rd'), ('rebol', 'REBOL'), ('red', 'Red'), ('redcode', 'Redcode'), ('registry', 'reg'), ('resource', 'ResourceBundle'), ('rexx', 'Rexx'), ('rhtml', 'RHTML'), ('robotframework', 'RobotFramework'), ('rql', 'RQL'), ('rsl', 'RSL'), ('rst', 'reStructuredText'), ('rust', 'Rust'), ('sass', 'Sass'), ('scala', 'Scala'), ('scaml', 'Scaml'), ('scheme', 'Scheme'), ('scilab', 'Scilab'), ('scss', 'SCSS'), ('shell-session', 'Shell Session'), ('slim', 'Slim'), ('smali', 'Smali'), ('smalltalk', 'Smalltalk'), ('smarty', 'Smarty'), ('sml', 'Standard ML'), ('snobol', 'Snobol'), ('sourceslist', 'Debian Sourcelist'), ('sp', 'SourcePawn'), ('sparql', 'SPARQL'), ('spec', 'RPMSpec'), ('splus', 'S'), ('sql', 'SQL'), ('sqlite3', 'sqlite3con'), ('squidconf', 'SquidConf'), ('ssp', 'Scalate Server Page'), ('stan', 'Stan'), ('swift', 'Swift'), ('swig', 'SWIG'), ('systemverilog', 'systemverilog'), ('tads3', 'TADS 3'), ('tcl', 'Tcl'), ('tcsh', 'Tcsh'), ('tea', 'Tea'), ('tex', 'TeX'), ('text', 'Text only'), ('todotxt', 'Todotxt'), ('trac-wiki', 'MoinMoin/Trac Wiki markup'), ('treetop', 'Treetop'), ('ts', 'TypeScript'), ('twig', 'Twig'), ('urbiscript', 'UrbiScript'), ('vala', 'Vala'), ('vb.net', 'VB.net'), ('vctreestatus', 'VCTreeStatus'), ('velocity', 'Velocity'), ('verilog', 'verilog'), ('vgl', 'VGL'), ('vhdl', 'vhdl'), ('vim', 'VimL'), ('xml', 'XML'), ('xml+cheetah', 'XML+Cheetah'), ('xml+django', 'XML+Django/Jinja'), ('xml+erb', 'XML+Ruby'), ('xml+evoque', 'XML+Evoque'), ('xml+lasso', 'XML+Lasso'), ('xml+mako', 'XML+Mako'), ('xml+myghty', 'XML+Myghty'), ('xml+php', 'XML+PHP'), ('xml+smarty', 'XML+Smarty'), ('xml+velocity', 'XML+Velocity'), ('xquery', 'XQuery'), ('xslt', 'XSLT'), ('xtend', 'Xtend'), ('xul+mozpreproc', 'XUL+mozpreproc'), ('yaml', 'YAML'), ('yaml+jinja', 'YAML+Jinja'), ('zephir', 'Zephir')], default='python', max_length=100), 19 | ), 20 | ] 21 | -------------------------------------------------------------------------------- /example_app/snippets/migrations/0003_auto_20160718_0720.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by Django 1.9.7 on 2016-07-18 12:20 3 | from __future__ import unicode_literals 4 | 5 | from django.db import migrations, models 6 | 7 | 8 | class Migration(migrations.Migration): 9 | 10 | dependencies = [ 11 | ('snippets', '0002_auto_20160717_2140'), 12 | ] 13 | 14 | operations = [ 15 | migrations.AlterField( 16 | model_name='snippet', 17 | name='language', 18 | field=models.CharField(choices=[('abap', 'ABAP'), ('ada', 'Ada'), ('agda', 'Agda'), ('ahk', 'autohotkey'), ('alloy', 'Alloy'), ('antlr', 'ANTLR'), ('antlr-as', 'ANTLR With ActionScript Target'), ('antlr-cpp', 'ANTLR With CPP Target'), ('antlr-csharp', 'ANTLR With C# Target'), ('antlr-java', 'ANTLR With Java Target'), ('antlr-objc', 'ANTLR With ObjectiveC Target'), ('antlr-perl', 'ANTLR With Perl Target'), ('antlr-python', 'ANTLR With Python Target'), ('antlr-ruby', 'ANTLR With Ruby Target'), ('apacheconf', 'ApacheConf'), ('apl', 'APL'), ('applescript', 'AppleScript'), ('as', 'ActionScript'), ('as3', 'ActionScript 3'), ('aspectj', 'AspectJ'), ('aspx-cs', 'aspx-cs'), ('aspx-vb', 'aspx-vb'), ('asy', 'Asymptote'), ('at', 'AmbientTalk'), ('autoit', 'AutoIt'), ('awk', 'Awk'), ('basemake', 'Base Makefile'), ('bash', 'Bash'), ('bat', 'Batchfile'), ('bbcode', 'BBCode'), ('befunge', 'Befunge'), ('blitzbasic', 'BlitzBasic'), ('blitzmax', 'BlitzMax'), ('boo', 'Boo'), ('brainfuck', 'Brainfuck'), ('bro', 'Bro'), ('bugs', 'BUGS'), ('c', 'C'), ('c-objdump', 'c-objdump'), ('ca65', 'ca65 assembler'), ('cbmbas', 'CBM BASIC V2'), ('ceylon', 'Ceylon'), ('cfc', 'Coldfusion CFC'), ('cfengine3', 'CFEngine3'), ('cfm', 'Coldfusion HTML'), ('cfs', 'cfstatement'), ('chai', 'ChaiScript'), ('chapel', 'Chapel'), ('cheetah', 'Cheetah'), ('cirru', 'Cirru'), ('clay', 'Clay'), ('clojure', 'Clojure'), ('clojurescript', 'ClojureScript'), ('cmake', 'CMake'), ('cobol', 'COBOL'), ('cobolfree', 'COBOLFree'), ('coffee-script', 'CoffeeScript'), ('common-lisp', 'Common Lisp'), ('console', 'Bash Session'), ('control', 'Debian Control file'), ('coq', 'Coq'), ('cpp', 'C++'), ('cpp-objdump', 'cpp-objdump'), ('croc', 'Croc'), ('cryptol', 'Cryptol'), ('csharp', 'C#'), ('css', 'CSS'), ('css+django', 'CSS+Django/Jinja'), ('css+erb', 'CSS+Ruby'), ('css+genshitext', 'CSS+Genshi Text'), ('css+lasso', 'CSS+Lasso'), ('css+mako', 'CSS+Mako'), ('css+mozpreproc', 'CSS+mozpreproc'), ('css+myghty', 'CSS+Myghty'), ('css+php', 'CSS+PHP'), ('css+smarty', 'CSS+Smarty'), ('cucumber', 'Gherkin'), ('cuda', 'CUDA'), ('cypher', 'Cypher'), ('cython', 'Cython'), ('d', 'D'), ('d-objdump', 'd-objdump'), ('dart', 'Dart'), ('delphi', 'Delphi'), ('dg', 'dg'), ('diff', 'Diff'), ('django', 'Django/Jinja'), ('docker', 'Docker'), ('dpatch', 'Darcs Patch'), ('dtd', 'DTD'), ('duel', 'Duel'), ('dylan', 'Dylan'), ('dylan-console', 'Dylan session'), ('dylan-lid', 'DylanLID'), ('ebnf', 'EBNF'), ('ec', 'eC'), ('ecl', 'ECL'), ('eiffel', 'Eiffel'), ('elixir', 'Elixir'), ('erb', 'ERB'), ('erl', 'Erlang erl session'), ('erlang', 'Erlang'), ('evoque', 'Evoque'), ('factor', 'Factor'), ('fan', 'Fantom'), ('fancy', 'Fancy'), ('felix', 'Felix'), ('fortran', 'Fortran'), ('foxpro', 'FoxPro'), ('fsharp', 'FSharp'), ('gap', 'GAP'), ('gas', 'GAS'), ('genshi', 'Genshi'), ('genshitext', 'Genshi Text'), ('glsl', 'GLSL'), ('gnuplot', 'Gnuplot'), ('go', 'Go'), ('golo', 'Golo'), ('gooddata-cl', 'GoodData-CL'), ('gosu', 'Gosu'), ('groff', 'Groff'), ('groovy', 'Groovy'), ('gst', 'Gosu Template'), ('haml', 'Haml'), ('handlebars', 'Handlebars'), ('haskell', 'Haskell'), ('haxeml', 'Hxml'), ('html', 'HTML'), ('html+cheetah', 'HTML+Cheetah'), ('html+django', 'HTML+Django/Jinja'), ('html+evoque', 'HTML+Evoque'), ('html+genshi', 'HTML+Genshi'), ('html+handlebars', 'HTML+Handlebars'), ('html+lasso', 'HTML+Lasso'), ('html+mako', 'HTML+Mako'), ('html+myghty', 'HTML+Myghty'), ('html+php', 'HTML+PHP'), ('html+smarty', 'HTML+Smarty'), ('html+twig', 'HTML+Twig'), ('html+velocity', 'HTML+Velocity'), ('http', 'HTTP'), ('hx', 'Haxe'), ('hybris', 'Hybris'), ('hylang', 'Hy'), ('i6t', 'Inform 6 template'), ('idl', 'IDL'), ('idris', 'Idris'), ('iex', 'Elixir iex session'), ('igor', 'Igor'), ('inform6', 'Inform 6'), ('inform7', 'Inform 7'), ('ini', 'INI'), ('io', 'Io'), ('ioke', 'Ioke'), ('irc', 'IRC logs'), ('isabelle', 'Isabelle'), ('jade', 'Jade'), ('jags', 'JAGS'), ('jasmin', 'Jasmin'), ('java', 'Java'), ('javascript+mozpreproc', 'Javascript+mozpreproc'), ('jlcon', 'Julia console'), ('js', 'JavaScript'), ('js+cheetah', 'JavaScript+Cheetah'), ('js+django', 'JavaScript+Django/Jinja'), ('js+erb', 'JavaScript+Ruby'), ('js+genshitext', 'JavaScript+Genshi Text'), ('js+lasso', 'JavaScript+Lasso'), ('js+mako', 'JavaScript+Mako'), ('js+myghty', 'JavaScript+Myghty'), ('js+php', 'JavaScript+PHP'), ('js+smarty', 'JavaScript+Smarty'), ('json', 'JSON'), ('jsonld', 'JSON-LD'), ('jsp', 'Java Server Page'), ('julia', 'Julia'), ('kal', 'Kal'), ('kconfig', 'Kconfig'), ('koka', 'Koka'), ('kotlin', 'Kotlin'), ('lagda', 'Literate Agda'), ('lasso', 'Lasso'), ('lcry', 'Literate Cryptol'), ('lean', 'Lean'), ('lhs', 'Literate Haskell'), ('lidr', 'Literate Idris'), ('lighty', 'Lighttpd configuration file'), ('limbo', 'Limbo'), ('liquid', 'liquid'), ('live-script', 'LiveScript'), ('llvm', 'LLVM'), ('logos', 'Logos'), ('logtalk', 'Logtalk'), ('lsl', 'LSL'), ('lua', 'Lua'), ('make', 'Makefile'), ('mako', 'Mako'), ('maql', 'MAQL'), ('mask', 'Mask'), ('mason', 'Mason'), ('mathematica', 'Mathematica'), ('matlab', 'Matlab'), ('matlabsession', 'Matlab session'), ('minid', 'MiniD'), ('modelica', 'Modelica'), ('modula2', 'Modula-2'), ('monkey', 'Monkey'), ('moocode', 'MOOCode'), ('moon', 'MoonScript'), ('mozhashpreproc', 'mozhashpreproc'), ('mozpercentpreproc', 'mozpercentpreproc'), ('mql', 'MQL'), ('mscgen', 'Mscgen'), ('mupad', 'MuPAD'), ('mxml', 'MXML'), ('myghty', 'Myghty'), ('mysql', 'MySQL'), ('nasm', 'NASM'), ('nemerle', 'Nemerle'), ('nesc', 'nesC'), ('newlisp', 'NewLisp'), ('newspeak', 'Newspeak'), ('nginx', 'Nginx configuration file'), ('nimrod', 'Nimrod'), ('nit', 'Nit'), ('nixos', 'Nix'), ('nsis', 'NSIS'), ('numpy', 'NumPy'), ('objdump', 'objdump'), ('objdump-nasm', 'objdump-nasm'), ('objective-c', 'Objective-C'), ('objective-c++', 'Objective-C++'), ('objective-j', 'Objective-J'), ('ocaml', 'OCaml'), ('octave', 'Octave'), ('ooc', 'Ooc'), ('opa', 'Opa'), ('openedge', 'OpenEdge ABL'), ('pan', 'Pan'), ('pawn', 'Pawn'), ('perl', 'Perl'), ('perl6', 'Perl6'), ('php', 'PHP'), ('pig', 'Pig'), ('pike', 'Pike'), ('plpgsql', 'PL/pgSQL'), ('postgresql', 'PostgreSQL SQL dialect'), ('postscript', 'PostScript'), ('pot', 'Gettext Catalog'), ('pov', 'POVRay'), ('powershell', 'PowerShell'), ('prolog', 'Prolog'), ('properties', 'Properties'), ('protobuf', 'Protocol Buffer'), ('psql', 'PostgreSQL console (psql)'), ('puppet', 'Puppet'), ('py3tb', 'Python 3.0 Traceback'), ('pycon', 'Python console session'), ('pypylog', 'PyPy Log'), ('pytb', 'Python Traceback'), ('python', 'Python'), ('python3', 'Python 3'), ('qbasic', 'QBasic'), ('qml', 'QML'), ('racket', 'Racket'), ('ragel', 'Ragel'), ('ragel-c', 'Ragel in C Host'), ('ragel-cpp', 'Ragel in CPP Host'), ('ragel-d', 'Ragel in D Host'), ('ragel-em', 'Embedded Ragel'), ('ragel-java', 'Ragel in Java Host'), ('ragel-objc', 'Ragel in Objective C Host'), ('ragel-ruby', 'Ragel in Ruby Host'), ('raw', 'Raw token data'), ('rb', 'Ruby'), ('rbcon', 'Ruby irb session'), ('rconsole', 'RConsole'), ('rd', 'Rd'), ('rebol', 'REBOL'), ('red', 'Red'), ('redcode', 'Redcode'), ('registry', 'reg'), ('resource', 'ResourceBundle'), ('rexx', 'Rexx'), ('rhtml', 'RHTML'), ('robotframework', 'RobotFramework'), ('rql', 'RQL'), ('rsl', 'RSL'), ('rst', 'reStructuredText'), ('rust', 'Rust'), ('sass', 'Sass'), ('scala', 'Scala'), ('scaml', 'Scaml'), ('scheme', 'Scheme'), ('scilab', 'Scilab'), ('scss', 'SCSS'), ('shell-session', 'Shell Session'), ('slim', 'Slim'), ('smali', 'Smali'), ('smalltalk', 'Smalltalk'), ('smarty', 'Smarty'), ('sml', 'Standard ML'), ('snobol', 'Snobol'), ('sourceslist', 'Debian Sourcelist'), ('sp', 'SourcePawn'), ('sparql', 'SPARQL'), ('spec', 'RPMSpec'), ('splus', 'S'), ('sql', 'SQL'), ('sqlite3', 'sqlite3con'), ('squidconf', 'SquidConf'), ('ssp', 'Scalate Server Page'), ('stan', 'Stan'), ('swift', 'Swift'), ('swig', 'SWIG'), ('systemverilog', 'systemverilog'), ('tads3', 'TADS 3'), ('tcl', 'Tcl'), ('tcsh', 'Tcsh'), ('tea', 'Tea'), ('tex', 'TeX'), ('text', 'Text only'), ('todotxt', 'Todotxt'), ('trac-wiki', 'MoinMoin/Trac Wiki markup'), ('treetop', 'Treetop'), ('ts', 'TypeScript'), ('twig', 'Twig'), ('urbiscript', 'UrbiScript'), ('vala', 'Vala'), ('vb.net', 'VB.net'), ('vctreestatus', 'VCTreeStatus'), ('velocity', 'Velocity'), ('verilog', 'verilog'), ('vgl', 'VGL'), ('vhdl', 'vhdl'), ('vim', 'VimL'), ('xml', 'XML'), ('xml+cheetah', 'XML+Cheetah'), ('xml+django', 'XML+Django/Jinja'), ('xml+erb', 'XML+Ruby'), ('xml+evoque', 'XML+Evoque'), ('xml+lasso', 'XML+Lasso'), ('xml+mako', 'XML+Mako'), ('xml+myghty', 'XML+Myghty'), ('xml+php', 'XML+PHP'), ('xml+smarty', 'XML+Smarty'), ('xml+velocity', 'XML+Velocity'), ('xquery', 'XQuery'), ('xslt', 'XSLT'), ('xtend', 'Xtend'), ('xul+mozpreproc', 'XUL+mozpreproc'), ('yaml', 'YAML'), ('yaml+jinja', 'YAML+Jinja'), ('zephir', 'Zephir')], default='python', max_length=100), 19 | ), 20 | ] 21 | -------------------------------------------------------------------------------- /example_app/snippets/migrations/0004_auto_20180430_1036.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.0.4 on 2018-04-30 15:36 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('snippets', '0003_auto_20160718_0720'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AlterField( 14 | model_name='snippet', 15 | name='language', 16 | field=models.CharField(choices=[('abap', 'ABAP'), ('abnf', 'ABNF'), ('ada', 'Ada'), ('adl', 'ADL'), ('agda', 'Agda'), ('aheui', 'Aheui'), ('ahk', 'autohotkey'), ('alloy', 'Alloy'), ('ampl', 'Ampl'), ('antlr', 'ANTLR'), ('antlr-as', 'ANTLR With ActionScript Target'), ('antlr-cpp', 'ANTLR With CPP Target'), ('antlr-csharp', 'ANTLR With C# Target'), ('antlr-java', 'ANTLR With Java Target'), ('antlr-objc', 'ANTLR With ObjectiveC Target'), ('antlr-perl', 'ANTLR With Perl Target'), ('antlr-python', 'ANTLR With Python Target'), ('antlr-ruby', 'ANTLR With Ruby Target'), ('apacheconf', 'ApacheConf'), ('apl', 'APL'), ('applescript', 'AppleScript'), ('arduino', 'Arduino'), ('as', 'ActionScript'), ('as3', 'ActionScript 3'), ('aspectj', 'AspectJ'), ('aspx-cs', 'aspx-cs'), ('aspx-vb', 'aspx-vb'), ('asy', 'Asymptote'), ('at', 'AmbientTalk'), ('autoit', 'AutoIt'), ('awk', 'Awk'), ('basemake', 'Base Makefile'), ('bash', 'Bash'), ('bat', 'Batchfile'), ('bbcode', 'BBCode'), ('bc', 'BC'), ('befunge', 'Befunge'), ('bib', 'BibTeX'), ('blitzbasic', 'BlitzBasic'), ('blitzmax', 'BlitzMax'), ('bnf', 'BNF'), ('boo', 'Boo'), ('boogie', 'Boogie'), ('brainfuck', 'Brainfuck'), ('bro', 'Bro'), ('bst', 'BST'), ('bugs', 'BUGS'), ('c', 'C'), ('c-objdump', 'c-objdump'), ('ca65', 'ca65 assembler'), ('cadl', 'cADL'), ('camkes', 'CAmkES'), ('capdl', 'CapDL'), ('capnp', "Cap'n Proto"), ('cbmbas', 'CBM BASIC V2'), ('ceylon', 'Ceylon'), ('cfc', 'Coldfusion CFC'), ('cfengine3', 'CFEngine3'), ('cfm', 'Coldfusion HTML'), ('cfs', 'cfstatement'), ('chai', 'ChaiScript'), ('chapel', 'Chapel'), ('cheetah', 'Cheetah'), ('cirru', 'Cirru'), ('clay', 'Clay'), ('clean', 'Clean'), ('clojure', 'Clojure'), ('clojurescript', 'ClojureScript'), ('cmake', 'CMake'), ('cobol', 'COBOL'), ('cobolfree', 'COBOLFree'), ('coffee-script', 'CoffeeScript'), ('common-lisp', 'Common Lisp'), ('componentpascal', 'Component Pascal'), ('console', 'Bash Session'), ('control', 'Debian Control file'), ('coq', 'Coq'), ('cpp', 'C++'), ('cpp-objdump', 'cpp-objdump'), ('cpsa', 'CPSA'), ('cr', 'Crystal'), ('crmsh', 'Crmsh'), ('croc', 'Croc'), ('cryptol', 'Cryptol'), ('csharp', 'C#'), ('csound', 'Csound Orchestra'), ('csound-document', 'Csound Document'), ('csound-score', 'Csound Score'), ('css', 'CSS'), ('css+django', 'CSS+Django/Jinja'), ('css+erb', 'CSS+Ruby'), ('css+genshitext', 'CSS+Genshi Text'), ('css+lasso', 'CSS+Lasso'), ('css+mako', 'CSS+Mako'), ('css+mozpreproc', 'CSS+mozpreproc'), ('css+myghty', 'CSS+Myghty'), ('css+php', 'CSS+PHP'), ('css+smarty', 'CSS+Smarty'), ('cucumber', 'Gherkin'), ('cuda', 'CUDA'), ('cypher', 'Cypher'), ('cython', 'Cython'), ('d', 'D'), ('d-objdump', 'd-objdump'), ('dart', 'Dart'), ('delphi', 'Delphi'), ('dg', 'dg'), ('diff', 'Diff'), ('django', 'Django/Jinja'), ('docker', 'Docker'), ('doscon', 'MSDOS Session'), ('dpatch', 'Darcs Patch'), ('dtd', 'DTD'), ('duel', 'Duel'), ('dylan', 'Dylan'), ('dylan-console', 'Dylan session'), ('dylan-lid', 'DylanLID'), ('earl-grey', 'Earl Grey'), ('easytrieve', 'Easytrieve'), ('ebnf', 'EBNF'), ('ec', 'eC'), ('ecl', 'ECL'), ('eiffel', 'Eiffel'), ('elixir', 'Elixir'), ('elm', 'Elm'), ('emacs', 'EmacsLisp'), ('erb', 'ERB'), ('erl', 'Erlang erl session'), ('erlang', 'Erlang'), ('evoque', 'Evoque'), ('extempore', 'xtlang'), ('ezhil', 'Ezhil'), ('factor', 'Factor'), ('fan', 'Fantom'), ('fancy', 'Fancy'), ('felix', 'Felix'), ('fish', 'Fish'), ('flatline', 'Flatline'), ('forth', 'Forth'), ('fortran', 'Fortran'), ('fortranfixed', 'FortranFixed'), ('foxpro', 'FoxPro'), ('fsharp', 'FSharp'), ('gap', 'GAP'), ('gas', 'GAS'), ('genshi', 'Genshi'), ('genshitext', 'Genshi Text'), ('glsl', 'GLSL'), ('gnuplot', 'Gnuplot'), ('go', 'Go'), ('golo', 'Golo'), ('gooddata-cl', 'GoodData-CL'), ('gosu', 'Gosu'), ('groff', 'Groff'), ('groovy', 'Groovy'), ('gst', 'Gosu Template'), ('haml', 'Haml'), ('handlebars', 'Handlebars'), ('haskell', 'Haskell'), ('haxeml', 'Hxml'), ('hexdump', 'Hexdump'), ('hsail', 'HSAIL'), ('html', 'HTML'), ('html+cheetah', 'HTML+Cheetah'), ('html+django', 'HTML+Django/Jinja'), ('html+evoque', 'HTML+Evoque'), ('html+genshi', 'HTML+Genshi'), ('html+handlebars', 'HTML+Handlebars'), ('html+lasso', 'HTML+Lasso'), ('html+mako', 'HTML+Mako'), ('html+myghty', 'HTML+Myghty'), ('html+ng2', 'HTML + Angular2'), ('html+php', 'HTML+PHP'), ('html+smarty', 'HTML+Smarty'), ('html+twig', 'HTML+Twig'), ('html+velocity', 'HTML+Velocity'), ('http', 'HTTP'), ('hx', 'Haxe'), ('hybris', 'Hybris'), ('hylang', 'Hy'), ('i6t', 'Inform 6 template'), ('idl', 'IDL'), ('idris', 'Idris'), ('iex', 'Elixir iex session'), ('igor', 'Igor'), ('inform6', 'Inform 6'), ('inform7', 'Inform 7'), ('ini', 'INI'), ('io', 'Io'), ('ioke', 'Ioke'), ('ipython2', 'IPython'), ('ipython3', 'IPython3'), ('ipythonconsole', 'IPython console session'), ('irc', 'IRC logs'), ('isabelle', 'Isabelle'), ('j', 'J'), ('jags', 'JAGS'), ('jasmin', 'Jasmin'), ('java', 'Java'), ('javascript+mozpreproc', 'Javascript+mozpreproc'), ('jcl', 'JCL'), ('jlcon', 'Julia console'), ('js', 'JavaScript'), ('js+cheetah', 'JavaScript+Cheetah'), ('js+django', 'JavaScript+Django/Jinja'), ('js+erb', 'JavaScript+Ruby'), ('js+genshitext', 'JavaScript+Genshi Text'), ('js+lasso', 'JavaScript+Lasso'), ('js+mako', 'JavaScript+Mako'), ('js+myghty', 'JavaScript+Myghty'), ('js+php', 'JavaScript+PHP'), ('js+smarty', 'JavaScript+Smarty'), ('jsgf', 'JSGF'), ('json', 'JSON'), ('json-object', 'JSONBareObject'), ('jsonld', 'JSON-LD'), ('jsp', 'Java Server Page'), ('julia', 'Julia'), ('juttle', 'Juttle'), ('kal', 'Kal'), ('kconfig', 'Kconfig'), ('koka', 'Koka'), ('kotlin', 'Kotlin'), ('lagda', 'Literate Agda'), ('lasso', 'Lasso'), ('lcry', 'Literate Cryptol'), ('lean', 'Lean'), ('less', 'LessCss'), ('lhs', 'Literate Haskell'), ('lidr', 'Literate Idris'), ('lighty', 'Lighttpd configuration file'), ('limbo', 'Limbo'), ('liquid', 'liquid'), ('live-script', 'LiveScript'), ('llvm', 'LLVM'), ('logos', 'Logos'), ('logtalk', 'Logtalk'), ('lsl', 'LSL'), ('lua', 'Lua'), ('make', 'Makefile'), ('mako', 'Mako'), ('maql', 'MAQL'), ('mask', 'Mask'), ('mason', 'Mason'), ('mathematica', 'Mathematica'), ('matlab', 'Matlab'), ('matlabsession', 'Matlab session'), ('md', 'markdown'), ('minid', 'MiniD'), ('modelica', 'Modelica'), ('modula2', 'Modula-2'), ('monkey', 'Monkey'), ('monte', 'Monte'), ('moocode', 'MOOCode'), ('moon', 'MoonScript'), ('mozhashpreproc', 'mozhashpreproc'), ('mozpercentpreproc', 'mozpercentpreproc'), ('mql', 'MQL'), ('mscgen', 'Mscgen'), ('mupad', 'MuPAD'), ('mxml', 'MXML'), ('myghty', 'Myghty'), ('mysql', 'MySQL'), ('nasm', 'NASM'), ('ncl', 'NCL'), ('nemerle', 'Nemerle'), ('nesc', 'nesC'), ('newlisp', 'NewLisp'), ('newspeak', 'Newspeak'), ('ng2', 'Angular2'), ('nginx', 'Nginx configuration file'), ('nim', 'Nimrod'), ('nit', 'Nit'), ('nixos', 'Nix'), ('nsis', 'NSIS'), ('numpy', 'NumPy'), ('nusmv', 'NuSMV'), ('objdump', 'objdump'), ('objdump-nasm', 'objdump-nasm'), ('objective-c', 'Objective-C'), ('objective-c++', 'Objective-C++'), ('objective-j', 'Objective-J'), ('ocaml', 'OCaml'), ('octave', 'Octave'), ('odin', 'ODIN'), ('ooc', 'Ooc'), ('opa', 'Opa'), ('openedge', 'OpenEdge ABL'), ('pacmanconf', 'PacmanConf'), ('pan', 'Pan'), ('parasail', 'ParaSail'), ('pawn', 'Pawn'), ('perl', 'Perl'), ('perl6', 'Perl6'), ('php', 'PHP'), ('pig', 'Pig'), ('pike', 'Pike'), ('pkgconfig', 'PkgConfig'), ('plpgsql', 'PL/pgSQL'), ('postgresql', 'PostgreSQL SQL dialect'), ('postscript', 'PostScript'), ('pot', 'Gettext Catalog'), ('pov', 'POVRay'), ('powershell', 'PowerShell'), ('praat', 'Praat'), ('prolog', 'Prolog'), ('properties', 'Properties'), ('protobuf', 'Protocol Buffer'), ('ps1con', 'PowerShell Session'), ('psql', 'PostgreSQL console (psql)'), ('pug', 'Pug'), ('puppet', 'Puppet'), ('py3tb', 'Python 3.0 Traceback'), ('pycon', 'Python console session'), ('pypylog', 'PyPy Log'), ('pytb', 'Python Traceback'), ('python', 'Python'), ('python3', 'Python 3'), ('qbasic', 'QBasic'), ('qml', 'QML'), ('qvto', 'QVTO'), ('racket', 'Racket'), ('ragel', 'Ragel'), ('ragel-c', 'Ragel in C Host'), ('ragel-cpp', 'Ragel in CPP Host'), ('ragel-d', 'Ragel in D Host'), ('ragel-em', 'Embedded Ragel'), ('ragel-java', 'Ragel in Java Host'), ('ragel-objc', 'Ragel in Objective C Host'), ('ragel-ruby', 'Ragel in Ruby Host'), ('raw', 'Raw token data'), ('rb', 'Ruby'), ('rbcon', 'Ruby irb session'), ('rconsole', 'RConsole'), ('rd', 'Rd'), ('rebol', 'REBOL'), ('red', 'Red'), ('redcode', 'Redcode'), ('registry', 'reg'), ('resource', 'ResourceBundle'), ('rexx', 'Rexx'), ('rhtml', 'RHTML'), ('rnc', 'Relax-NG Compact'), ('roboconf-graph', 'Roboconf Graph'), ('roboconf-instances', 'Roboconf Instances'), ('robotframework', 'RobotFramework'), ('rql', 'RQL'), ('rsl', 'RSL'), ('rst', 'reStructuredText'), ('rts', 'TrafficScript'), ('rust', 'Rust'), ('sas', 'SAS'), ('sass', 'Sass'), ('sc', 'SuperCollider'), ('scala', 'Scala'), ('scaml', 'Scaml'), ('scheme', 'Scheme'), ('scilab', 'Scilab'), ('scss', 'SCSS'), ('shen', 'Shen'), ('silver', 'Silver'), ('slim', 'Slim'), ('smali', 'Smali'), ('smalltalk', 'Smalltalk'), ('smarty', 'Smarty'), ('sml', 'Standard ML'), ('snobol', 'Snobol'), ('snowball', 'Snowball'), ('sourceslist', 'Debian Sourcelist'), ('sp', 'SourcePawn'), ('sparql', 'SPARQL'), ('spec', 'RPMSpec'), ('splus', 'S'), ('sql', 'SQL'), ('sqlite3', 'sqlite3con'), ('squidconf', 'SquidConf'), ('ssp', 'Scalate Server Page'), ('stan', 'Stan'), ('stata', 'Stata'), ('swift', 'Swift'), ('swig', 'SWIG'), ('systemverilog', 'systemverilog'), ('tads3', 'TADS 3'), ('tap', 'TAP'), ('tasm', 'TASM'), ('tcl', 'Tcl'), ('tcsh', 'Tcsh'), ('tcshcon', 'Tcsh Session'), ('tea', 'Tea'), ('termcap', 'Termcap'), ('terminfo', 'Terminfo'), ('terraform', 'Terraform'), ('tex', 'TeX'), ('text', 'Text only'), ('thrift', 'Thrift'), ('todotxt', 'Todotxt'), ('trac-wiki', 'MoinMoin/Trac Wiki markup'), ('treetop', 'Treetop'), ('ts', 'TypeScript'), ('tsql', 'Transact-SQL'), ('turtle', 'Turtle'), ('twig', 'Twig'), ('typoscript', 'TypoScript'), ('typoscriptcssdata', 'TypoScriptCssData'), ('typoscripthtmldata', 'TypoScriptHtmlData'), ('urbiscript', 'UrbiScript'), ('vala', 'Vala'), ('vb.net', 'VB.net'), ('vcl', 'VCL'), ('vclsnippets', 'VCLSnippets'), ('vctreestatus', 'VCTreeStatus'), ('velocity', 'Velocity'), ('verilog', 'verilog'), ('vgl', 'VGL'), ('vhdl', 'vhdl'), ('vim', 'VimL'), ('wdiff', 'WDiff'), ('whiley', 'Whiley'), ('x10', 'X10'), ('xml', 'XML'), ('xml+cheetah', 'XML+Cheetah'), ('xml+django', 'XML+Django/Jinja'), ('xml+erb', 'XML+Ruby'), ('xml+evoque', 'XML+Evoque'), ('xml+lasso', 'XML+Lasso'), ('xml+mako', 'XML+Mako'), ('xml+myghty', 'XML+Myghty'), ('xml+php', 'XML+PHP'), ('xml+smarty', 'XML+Smarty'), ('xml+velocity', 'XML+Velocity'), ('xquery', 'XQuery'), ('xslt', 'XSLT'), ('xtend', 'Xtend'), ('xul+mozpreproc', 'XUL+mozpreproc'), ('yaml', 'YAML'), ('yaml+jinja', 'YAML+Jinja'), ('zephir', 'Zephir')], default='python', max_length=100), 17 | ), 18 | migrations.AlterField( 19 | model_name='snippet', 20 | name='style', 21 | field=models.CharField(choices=[('abap', 'abap'), ('algol', 'algol'), ('algol_nu', 'algol_nu'), ('arduino', 'arduino'), ('autumn', 'autumn'), ('borland', 'borland'), ('bw', 'bw'), ('colorful', 'colorful'), ('default', 'default'), ('emacs', 'emacs'), ('friendly', 'friendly'), ('fruity', 'fruity'), ('igor', 'igor'), ('lovelace', 'lovelace'), ('manni', 'manni'), ('monokai', 'monokai'), ('murphy', 'murphy'), ('native', 'native'), ('paraiso-dark', 'paraiso-dark'), ('paraiso-light', 'paraiso-light'), ('pastie', 'pastie'), ('perldoc', 'perldoc'), ('rainbow_dash', 'rainbow_dash'), ('rrt', 'rrt'), ('tango', 'tango'), ('trac', 'trac'), ('vim', 'vim'), ('vs', 'vs'), ('xcode', 'xcode')], default='friendly', max_length=100), 22 | ), 23 | ] 24 | -------------------------------------------------------------------------------- /example_app/snippets/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bestdev322/django-rest-swagger/b69bc2dd7f9193fa5a8c7d130d5d0fd0f8538292/example_app/snippets/migrations/__init__.py -------------------------------------------------------------------------------- /example_app/snippets/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | from pygments.lexers import get_all_lexers 3 | from pygments.styles import get_all_styles 4 | from pygments.lexers import get_lexer_by_name 5 | from pygments.formatters.html import HtmlFormatter 6 | from pygments import highlight 7 | 8 | LEXERS = [item for item in get_all_lexers() if item[1]] 9 | LANGUAGE_CHOICES = sorted([(item[1][0], item[0]) for item in LEXERS]) 10 | STYLE_CHOICES = sorted((item, item) for item in get_all_styles()) 11 | 12 | 13 | class Snippet(models.Model): 14 | created = models.DateTimeField(auto_now_add=True) 15 | title = models.CharField(max_length=100, blank=True, default='') 16 | code = models.TextField() 17 | linenos = models.BooleanField(default=False) 18 | language = models.CharField( 19 | choices=LANGUAGE_CHOICES, 20 | default='python', 21 | max_length=100 22 | ) 23 | style = models.CharField( 24 | choices=STYLE_CHOICES, 25 | default='friendly', 26 | max_length=100 27 | ) 28 | owner = models.ForeignKey( 29 | 'auth.User', 30 | related_name='snippets', 31 | on_delete=models.CASCADE 32 | ) 33 | highlighted = models.TextField() 34 | 35 | class Meta: 36 | ordering = ('created',) 37 | 38 | def save(self, *args, **kwargs): 39 | """ 40 | Use the `pygments` library to create a highlighted HTML 41 | representation of the code snippet. 42 | """ 43 | lexer = get_lexer_by_name(self.language) 44 | linenos = self.linenos and 'table' or False 45 | options = self.title and {'title': self.title} or {} 46 | formatter = HtmlFormatter(style=self.style, linenos=linenos, 47 | full=True, **options) 48 | self.highlighted = highlight(self.code, lexer, formatter) 49 | super(Snippet, self).save(*args, **kwargs) 50 | 51 | # limit the number of instances retained 52 | snippets = Snippet.objects.all() 53 | if len(snippets) > 100: 54 | snippets[0].delete() 55 | -------------------------------------------------------------------------------- /example_app/snippets/permissions.py: -------------------------------------------------------------------------------- 1 | from rest_framework import permissions 2 | 3 | 4 | class IsOwnerOrReadOnly(permissions.BasePermission): 5 | """ 6 | Custom permission to only allow owners of an object to edit it. 7 | """ 8 | 9 | def has_object_permission(self, request, view, obj): 10 | # Read permissions are allowed to any request 11 | if request.method in permissions.SAFE_METHODS: 12 | return True 13 | 14 | # Write permissions are only allowed to the owner of the snippet 15 | return obj.owner == request.user 16 | -------------------------------------------------------------------------------- /example_app/snippets/serializers.py: -------------------------------------------------------------------------------- 1 | from rest_framework import serializers 2 | from snippets.models import Snippet 3 | from django.contrib.auth.models import User 4 | 5 | 6 | class SnippetSerializer(serializers.HyperlinkedModelSerializer): 7 | owner = serializers.ReadOnlyField(source='owner.username') 8 | highlight = serializers.HyperlinkedIdentityField(view_name='snippet-highlight', format='html') 9 | 10 | class Meta: 11 | model = Snippet 12 | fields = ('url', 'highlight', 'owner', 13 | 'title', 'code', 'linenos', 'language', 'style') 14 | 15 | class UserSerializer(serializers.HyperlinkedModelSerializer): 16 | snippets = serializers.HyperlinkedRelatedField(queryset=Snippet.objects.all(), view_name='snippet-detail', many=True) 17 | 18 | class Meta: 19 | model = User 20 | fields = ('url', 'username', 'snippets') 21 | -------------------------------------------------------------------------------- /example_app/snippets/views.py: -------------------------------------------------------------------------------- 1 | from django.contrib.auth.models import User 2 | from rest_framework import permissions 3 | from rest_framework import renderers 4 | from rest_framework import viewsets 5 | from rest_framework.decorators import detail_route 6 | from rest_framework.response import Response 7 | from snippets.models import Snippet 8 | from snippets.permissions import IsOwnerOrReadOnly 9 | from snippets.serializers import SnippetSerializer, UserSerializer 10 | 11 | 12 | class SnippetViewSet(viewsets.ModelViewSet): 13 | """ 14 | This endpoint presents code snippets. 15 | 16 | The `highlight` field presents a hyperlink to the highlighted HTML 17 | representation of the code snippet. 18 | 19 | The **owner** of the code snippet may update or delete instances 20 | of the code snippet. 21 | 22 | Try it yourself by logging in as one of these four users: **amy**, **max**, 23 | **jose** or **aziz**. The passwords are the same as the usernames. 24 | """ 25 | queryset = Snippet.objects.all() 26 | serializer_class = SnippetSerializer 27 | permission_classes = (permissions.IsAuthenticatedOrReadOnly, 28 | IsOwnerOrReadOnly,) 29 | 30 | @detail_route(renderer_classes=(renderers.StaticHTMLRenderer,)) 31 | def highlight(self, request, *args, **kwargs): 32 | snippet = self.get_object() 33 | return Response(snippet.highlighted) 34 | 35 | def perform_create(self, serializer): 36 | serializer.save(owner=self.request.user) 37 | 38 | 39 | class UserViewSet(viewsets.ReadOnlyModelViewSet): 40 | """ 41 | This endpoint presents the users in the system. 42 | 43 | As you can see, the collection of snippet instances owned by a user are 44 | serialized using a hyperlinked representation. 45 | """ 46 | queryset = User.objects.all() 47 | serializer_class = UserSerializer 48 | -------------------------------------------------------------------------------- /example_app/tutorial/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bestdev322/django-rest-swagger/b69bc2dd7f9193fa5a8c7d130d5d0fd0f8538292/example_app/tutorial/__init__.py -------------------------------------------------------------------------------- /example_app/tutorial/settings.py: -------------------------------------------------------------------------------- 1 | import os 2 | # Django settings for tutorial project. 3 | 4 | DEBUG = True 5 | 6 | ADMINS = ( 7 | # ('Your Name', 'your_email@example.com'), 8 | ) 9 | 10 | MANAGERS = ADMINS 11 | 12 | DATABASES = { 13 | 'default': { 14 | 'ENGINE': 'django.db.backends.sqlite3', # Or use an alternate database backend. 15 | 'NAME': 'tmp.db', # Path to sqlite3 database file. 16 | 'USER': '', # Not used with sqlite3. 17 | 'PASSWORD': '', # Not used with sqlite3. 18 | 'HOST': '', # Set to empty string for localhost. Not used with sqlite3. 19 | 'PORT': '', # Set to empty string for default. Not used with sqlite3. 20 | } 21 | } 22 | 23 | ALLOWED_HOSTS = ['*'] 24 | 25 | # Local time zone for this installation. Choices can be found here: 26 | # http://en.wikipedia.org/wiki/List_of_tz_zones_by_name 27 | # although not all choices may be available on all operating systems. 28 | # In a Windows environment this must be set to your system time zone. 29 | TIME_ZONE = 'America/Chicago' 30 | 31 | # Language code for this installation. All choices can be found here: 32 | # http://www.i18nguy.com/unicode/language-identifiers.html 33 | LANGUAGE_CODE = 'en-us' 34 | 35 | SITE_ID = 1 36 | 37 | # If you set this to False, Django will make some optimizations so as not 38 | # to load the internationalization machinery. 39 | USE_I18N = True 40 | 41 | # If you set this to False, Django will not format dates, numbers and 42 | # calendars according to the current locale. 43 | USE_L10N = True 44 | 45 | # If you set this to False, Django will not use timezone-aware datetimes. 46 | USE_TZ = True 47 | 48 | # Absolute filesystem path to the directory that will hold user-uploaded files. 49 | # Example: "/home/media/media.lawrence.com/media/" 50 | MEDIA_ROOT = '' 51 | 52 | # URL that handles the media served from MEDIA_ROOT. Make sure to use a 53 | # trailing slash. 54 | # Examples: "http://media.lawrence.com/media/", "http://example.com/media/" 55 | MEDIA_URL = '' 56 | 57 | # Absolute path to the directory static files should be collected to. 58 | # Don't put anything in this directory yourself; store your static files 59 | # in apps' "static/" subdirectories and in STATICFILES_DIRS. 60 | # Example: "/home/media/media.lawrence.com/static/" 61 | PROJECT_ROOT = os.path.dirname(os.path.abspath(__file__)) 62 | STATIC_ROOT = os.path.join(PROJECT_ROOT, 'staticfiles') 63 | 64 | # URL prefix for static files. 65 | # Example: "http://media.lawrence.com/static/" 66 | STATIC_URL = '/static/' 67 | 68 | # Additional locations of static files 69 | STATICFILES_DIRS = ( 70 | # Put strings here, like "/home/html/static" or "C:/www/django/static". 71 | # Always use forward slashes, even on Windows. 72 | # Don't forget to use absolute paths, not relative paths. 73 | ) 74 | 75 | # List of finder classes that know how to find static files in 76 | # various locations. 77 | STATICFILES_FINDERS = ( 78 | 'django.contrib.staticfiles.finders.FileSystemFinder', 79 | 'django.contrib.staticfiles.finders.AppDirectoriesFinder', 80 | # 'django.contrib.staticfiles.finders.DefaultStorageFinder', 81 | ) 82 | 83 | # Make this unique, and don't share it with anybody. 84 | SECRET_KEY = '98s9du5ruv!j%shx0udb#uz1g@v^xl65zm1l-_5%8cs6%c*qm$' 85 | 86 | MIDDLEWARE = ( 87 | 'whitenoise.middleware.WhiteNoiseMiddleware', 88 | 'django.contrib.sessions.middleware.SessionMiddleware', 89 | 'django.middleware.common.CommonMiddleware', 90 | 'django.middleware.csrf.CsrfViewMiddleware', 91 | 'django.contrib.auth.middleware.AuthenticationMiddleware', 92 | 'django.contrib.messages.middleware.MessageMiddleware', 93 | # Uncomment the next line for simple clickjacking protection: 94 | # 'django.middleware.clickjacking.XFrameOptionsMiddleware', 95 | ) 96 | 97 | ROOT_URLCONF = 'tutorial.urls' 98 | 99 | # Python dotted path to the WSGI application used by Django's runserver. 100 | WSGI_APPLICATION = 'tutorial.wsgi.application' 101 | 102 | TEMPLATES = [ 103 | { 104 | 'BACKEND': 'django.template.backends.django.DjangoTemplates', 105 | 'DIRS': [ 106 | ], 107 | 'APP_DIRS': True, 108 | 'OPTIONS': { 109 | 'context_processors': [ 110 | 'django.contrib.auth.context_processors.auth', 111 | 'django.template.context_processors.debug', 112 | 'django.template.context_processors.i18n', 113 | 'django.template.context_processors.media', 114 | 'django.template.context_processors.static', 115 | 'django.template.context_processors.tz', 116 | 'django.contrib.messages.context_processors.messages', 117 | ] 118 | } 119 | 120 | } 121 | ] 122 | 123 | INSTALLED_APPS = ( 124 | 'django.contrib.auth', 125 | 'django.contrib.contenttypes', 126 | 'django.contrib.sessions', 127 | 'django.contrib.sites', 128 | 'django.contrib.messages', 129 | 'django.contrib.staticfiles', 130 | # Uncomment the next line to enable the admin: 131 | # 'django.contrib.admin', 132 | # Uncomment the next line to enable admin documentation: 133 | # 'django.contrib.admindocs', 134 | 'rest_framework', 135 | 'rest_framework_swagger', 136 | 'snippets', 137 | ) 138 | 139 | SECURE_SSL_REDIRECT = bool(int(os.environ.get('SECURE_SSL_REDIRECT', 0))) 140 | USE_X_FORWARDED_HOST = SECURE_SSL_REDIRECT 141 | 142 | # A sample logging configuration. The only tangible logging 143 | # performed by this configuration is to send an email to 144 | # the site admins on every HTTP 500 error when DEBUG=False. 145 | # See http://docs.djangoproject.com/en/dev/topics/logging for 146 | # more details on how to customize your logging configuration. 147 | LOGGING = { 148 | 'version': 1, 149 | 'disable_existing_loggers': False, 150 | 'filters': { 151 | 'require_debug_false': { 152 | '()': 'django.utils.log.RequireDebugFalse' 153 | } 154 | }, 155 | 'handlers': { 156 | 'mail_admins': { 157 | 'level': 'ERROR', 158 | 'filters': ['require_debug_false'], 159 | 'class': 'django.utils.log.AdminEmailHandler' 160 | } 161 | }, 162 | 'loggers': { 163 | 'django.request': { 164 | 'handlers': ['mail_admins'], 165 | 'level': 'ERROR', 166 | 'propagate': True, 167 | }, 168 | } 169 | } 170 | 171 | REST_FRAMEWORK = { 172 | 'PAGE_SIZE': 10, 173 | 'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination' 174 | } 175 | 176 | SWAGGER_SETTINGS = { 177 | 'LOGIN_URL': 'rest_framework:login', 178 | 'LOGOUT_URL': 'rest_framework:logout', 179 | 'USE_SESSION_AUTH': True, 180 | 'DOC_EXPANSION': 'list', 181 | 'APIS_SORTER': 'alpha', 182 | 'SECURITY_DEFINITIONS': None, 183 | } 184 | 185 | 186 | import os 187 | if os.environ.get('HEROKU'): # heroku config:set HEROKU=1 188 | import dj_database_url 189 | DATABASES['default'] = dj_database_url.config() 190 | 191 | LOGIN_REDIRECT_URL = '/' 192 | -------------------------------------------------------------------------------- /example_app/tutorial/urls.py: -------------------------------------------------------------------------------- 1 | from django.conf.urls import url, include 2 | from rest_framework.routers import DefaultRouter 3 | from rest_framework_swagger.views import get_swagger_view 4 | 5 | from snippets import views 6 | 7 | 8 | router = DefaultRouter() 9 | router.register(r'snippets', views.SnippetViewSet) 10 | router.register(r'users', views.UserViewSet) 11 | 12 | schema_view = get_swagger_view(title='Snippets API') 13 | 14 | urlpatterns = [ 15 | url('^$', schema_view), 16 | url(r'^', include(router.urls)), 17 | url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')) 18 | ] 19 | -------------------------------------------------------------------------------- /example_app/tutorial/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for tutorial project. 3 | 4 | This module contains the WSGI application used by Django's development server 5 | and any production WSGI deployments. It should expose a module-level variable 6 | named ``application``. Django's ``runserver`` and ``runfcgi`` commands discover 7 | this application via the ``WSGI_APPLICATION`` setting. 8 | 9 | Usually you will have the standard Django WSGI application here, but it also 10 | might make sense to replace the whole Django WSGI application with a custom one 11 | that later delegates to the Django one. For example, you could introduce WSGI 12 | middleware here, or combine a Django application with an application of another 13 | framework. 14 | 15 | """ 16 | import os 17 | import sys 18 | sys.path.append(os.path.dirname(os.path.abspath(__file__)) + '/../../') 19 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "tutorial.settings") 20 | 21 | # This application object is used by any WSGI server configured to use this 22 | # file. This includes Django's development server, if the WSGI_APPLICATION 23 | # setting points here. 24 | from django.core.wsgi import get_wsgi_application 25 | application = get_wsgi_application() 26 | 27 | # Apply WSGI middleware here. 28 | # from helloworld.wsgi import HelloWorldApplication 29 | # application = HelloWorldApplication(application) 30 | -------------------------------------------------------------------------------- /mkdocs.yml: -------------------------------------------------------------------------------- 1 | site_name: Django REST Swagger 2 | repo_url: https://github.com/marcgibbons/django-rest-swagger 3 | repo_name: GitHub 4 | site_description: Swagger UI / OpenAPI Documentation for Django REST Framework 5 | site_author: Marc Gibbons 6 | copyright: 2013-2016 Marc Gibbons 7 | google_analytics: ['UA-80777383-1', 'auto'] 8 | pages: 9 | - Home: 'index.md' 10 | - Rendering the Schema: 'schema.md' 11 | - Settings: 'settings.md' 12 | - UI Customization: 'customization.md' 13 | -------------------------------------------------------------------------------- /pylintrc: -------------------------------------------------------------------------------- 1 | [MASTER] 2 | persistent=yes 3 | ignore=migrations 4 | cache-size=500 5 | 6 | [MESSAGES CONTROL] 7 | # C0111 Missing docstring 8 | # I0011 Warning locally suppressed using disable-msg 9 | # I0012 Warning locally suppressed using disable-msg 10 | # W0704 Except doesn't do anything Used when an except clause does nothing but "pass" and there is no "else" clause 11 | # W0142 Used * or * magic* Used when a function or method is called using *args or **kwargs to dispatch arguments. 12 | # W0212 Access to a protected member %s of a client class 13 | # W0232 Class has no __init__ method Used when a class has no __init__ method, neither its parent classes. 14 | # W0613 Unused argument %r Used when a function or method argument is not used. 15 | # W0702 No exception's type specified Used when an except clause doesn't specify exceptions type to catch. 16 | # R0201 Method could be a function 17 | # C1001 Used when a class is defined that does not inherit from anotherclass and does not inherit explicitly from “object”. 18 | # C0103 Invalid module name 19 | # R0901 Used when class has too many parent classes, try to reduce this to get a simpler (and so easier to use) class. 20 | # E1101 Used when an object (variable, function, …) is accessed for a non-existent member 21 | # W0223 Used when an abstract method (i.e. one that raises NotImplementedError) is not overridden in concrete class 22 | disable=C0111,I0011,I0012,W0704,W0142,W0212,W0232,W0613,W0702,R0201,C1001,C0103,R0901,E1101,W0223 23 | 24 | [REPORTS] 25 | msg-template={path}:{line}: [{msg_id}({symbol}), {obj}] {msg} 26 | 27 | 28 | [BASIC] 29 | no-docstring-rgx=__.*__|_.* 30 | class-rgx=[A-Z_][a-zA-Z0-9_]+$ 31 | function-rgx=[a-zA_][a-zA-Z0-9_]{2,70}$ 32 | method-rgx=[a-z_][a-zA-Z0-9_]{2,70}$ 33 | const-rgx=(([A-Z_][A-Z0-9_]*)|([a-z_][a-z0-9_]*)|(__.*__)|register|urlpatterns)$ 34 | good-names=_,i,j,k,e,qs,pk,setUp,tearDown 35 | 36 | [TYPECHECK] 37 | 38 | # Tells whether missing members accessed in mixin class should be ignored. A 39 | # mixin class is detected if its name ends with "mixin" (case insensitive). 40 | ignore-mixin-members=yes 41 | 42 | # List of classes names for which member attributes should not be checked 43 | # (useful for classes with attributes dynamically set). 44 | ignored-classes=SQLObject,WSGIRequest 45 | 46 | # List of members which are set dynamically and missed by pylint inference 47 | # system, and so shouldn't trigger E0201 when accessed. 48 | generated-members=objects,DoesNotExist,id,pk,_meta,base_fields,context 49 | 50 | # List of method names used to declare (i.e. assign) instance attributes 51 | defining-attr-methods=__init__,__new__,setUp 52 | 53 | 54 | [VARIABLES] 55 | init-import=no 56 | dummy-variables-rgx=_|dummy 57 | 58 | [SIMILARITIES] 59 | min-similarity-lines=8 60 | ignore-comments=yes 61 | ignore-docstrings=yes 62 | 63 | 64 | [MISCELLANEOUS] 65 | notes=FIXME,XXX 66 | 67 | 68 | [FORMAT] 69 | max-line-length=79 70 | max-module-lines=500 71 | indent-string=' ' 72 | 73 | 74 | [DESIGN] 75 | max-args=10 76 | max-locals=15 77 | max-returns=6 78 | max-branches=12 79 | max-statements=50 80 | max-parents=7 81 | max-attributes=10 82 | min-public-methods=0 83 | max-public-methods=50 84 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | Django==2.1.3 2 | djangorestframework==3.9.0 3 | coreapi==2.3.3 4 | openapi-codec==1.3.2 5 | simplejson==3.9.0 6 | 7 | # Testing 8 | tox==2.4.1 9 | pylint==1.8.4 10 | coverage==4.5.1 11 | ipdb==0.10.1 12 | 13 | # Docs 14 | mkdocs==0.15.3 15 | 16 | # Heroku 17 | dj_database_url==0.5.0 18 | psycopg2==2.7.4 19 | gunicorn==19.8.0 20 | whitenoise==3.3.1 21 | -------------------------------------------------------------------------------- /rest_framework_swagger/__init__.py: -------------------------------------------------------------------------------- 1 | __version__ = '2.2.0' 2 | -------------------------------------------------------------------------------- /rest_framework_swagger/renderers.py: -------------------------------------------------------------------------------- 1 | import coreapi 2 | from coreapi.compat import force_bytes 3 | from django.shortcuts import render, resolve_url 4 | from openapi_codec import OpenAPICodec as _OpenAPICodec 5 | from openapi_codec.encode import generate_swagger_object 6 | from rest_framework.renderers import BaseRenderer, JSONRenderer 7 | from rest_framework import status 8 | import simplejson as json 9 | 10 | from .settings import swagger_settings as settings 11 | 12 | 13 | class OpenAPICodec(_OpenAPICodec): 14 | def encode(self, document, **options): 15 | if not isinstance(document, coreapi.Document): 16 | raise TypeError('Expected a `coreapi.Document` instance') 17 | 18 | data = generate_swagger_object(document) 19 | data.update(**options) 20 | 21 | return force_bytes(json.dumps(data)) 22 | 23 | 24 | class OpenAPIRenderer(BaseRenderer): 25 | media_type = 'application/openapi+json' 26 | charset = None 27 | format = 'openapi' 28 | 29 | def render(self, data, accepted_media_type=None, renderer_context=None): 30 | if renderer_context['response'].status_code != status.HTTP_200_OK: 31 | return JSONRenderer().render(data) 32 | options = self.get_customizations() 33 | 34 | return OpenAPICodec().encode(data, **options) 35 | 36 | def get_customizations(self): 37 | """ 38 | Adds settings, overrides, etc. to the specification. 39 | """ 40 | data = {} 41 | if settings.SECURITY_DEFINITIONS: 42 | data['securityDefinitions'] = settings.SECURITY_DEFINITIONS 43 | 44 | return data 45 | 46 | 47 | class SwaggerUIRenderer(BaseRenderer): 48 | media_type = 'text/html' 49 | format = 'swagger' 50 | template = 'rest_framework_swagger/index.html' 51 | charset = 'utf-8' 52 | 53 | def render(self, data, accepted_media_type=None, renderer_context=None): 54 | self.set_context(data, renderer_context) 55 | return render( 56 | renderer_context['request'], 57 | self.template, 58 | renderer_context 59 | ) 60 | 61 | def set_context(self, data, renderer_context): 62 | renderer_context['USE_SESSION_AUTH'] = \ 63 | settings.USE_SESSION_AUTH 64 | renderer_context.update(self.get_auth_urls()) 65 | 66 | drs_settings = self.get_ui_settings() 67 | renderer_context['drs_settings'] = json.dumps(drs_settings) 68 | renderer_context['spec'] = OpenAPIRenderer().render( 69 | data=data, 70 | renderer_context=renderer_context 71 | ).decode() 72 | 73 | def get_auth_urls(self): 74 | urls = {} 75 | if settings.LOGIN_URL is not None: 76 | urls['LOGIN_URL'] = resolve_url(settings.LOGIN_URL) 77 | if settings.LOGOUT_URL is not None: 78 | urls['LOGOUT_URL'] = resolve_url(settings.LOGOUT_URL) 79 | 80 | return urls 81 | 82 | def get_ui_settings(self): 83 | data = { 84 | 'apisSorter': settings.APIS_SORTER, 85 | 'docExpansion': settings.DOC_EXPANSION, 86 | 'jsonEditor': settings.JSON_EDITOR, 87 | 'operationsSorter': settings.OPERATIONS_SORTER, 88 | 'showRequestHeaders': settings.SHOW_REQUEST_HEADERS, 89 | 'supportedSubmitMethods': settings.SUPPORTED_SUBMIT_METHODS, 90 | 'acceptHeaderVersion': settings.ACCEPT_HEADER_VERSION, 91 | 'customHeaders': settings.CUSTOM_HEADERS, 92 | } 93 | if settings.VALIDATOR_URL != '': 94 | data['validatorUrl'] = settings.VALIDATOR_URL 95 | 96 | return data 97 | -------------------------------------------------------------------------------- /rest_framework_swagger/settings.py: -------------------------------------------------------------------------------- 1 | from django.conf import settings 2 | from django.test.signals import setting_changed 3 | from rest_framework.settings import APISettings 4 | 5 | 6 | DEFAULTS = { 7 | 'USE_SESSION_AUTH': True, 8 | 'SECURITY_DEFINITIONS': { 9 | 'basic': { 10 | 'type': 'basic' 11 | } 12 | }, 13 | 'LOGIN_URL': getattr(settings, 'LOGIN_URL', None), 14 | 'LOGOUT_URL': getattr(settings, 'LOGOUT_URL', None), 15 | 'DOC_EXPANSION': None, 16 | 'APIS_SORTER': None, 17 | 'OPERATIONS_SORTER': None, 18 | 'JSON_EDITOR': False, 19 | 'SHOW_REQUEST_HEADERS': False, 20 | 'SUPPORTED_SUBMIT_METHODS': [ 21 | 'get', 22 | 'post', 23 | 'put', 24 | 'delete', 25 | 'patch' 26 | ], 27 | 'VALIDATOR_URL': '', 28 | 'ACCEPT_HEADER_VERSION': None, # e.g. '1.0' 29 | 'CUSTOM_HEADERS': {} # A dictionary of key/vals to override headers 30 | } 31 | 32 | IMPORT_STRINGS = [] 33 | 34 | swagger_settings = APISettings( 35 | user_settings=getattr(settings, 'SWAGGER_SETTINGS', {}), 36 | defaults=DEFAULTS, 37 | import_strings=IMPORT_STRINGS 38 | ) 39 | 40 | 41 | def reload_settings(*args, **kwargs): # pragma: no cover 42 | """ 43 | Reloads settings during unit tests if override_settings decorator 44 | is used. (Taken from DRF) 45 | """ 46 | # pylint: disable=W0603 47 | global swagger_settings 48 | 49 | if kwargs['setting'] == 'LOGIN_URL': 50 | swagger_settings.LOGIN_URL = kwargs['value'] 51 | if kwargs['setting'] == 'LOGOUT_URL': 52 | swagger_settings.LOGOUT_URL = kwargs['value'] 53 | if kwargs['setting'] != 'SWAGGER_SETTINGS': 54 | return 55 | 56 | swagger_settings = APISettings( 57 | kwargs['value'], 58 | DEFAULTS, 59 | IMPORT_STRINGS 60 | ) 61 | 62 | 63 | setting_changed.connect(reload_settings) 64 | -------------------------------------------------------------------------------- /rest_framework_swagger/static/rest_framework_swagger/bundles/app.bundle.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | padding: 0; 4 | } 5 | 6 | .swagger-ui .topbar a { 7 | flex: none; 8 | } 9 | 10 | .swagger-ui .topbar .download-url-wrapper .download-url-button { 11 | border-radius: 4px; 12 | } 13 | 14 | .swagger-ui .user-context { 15 | font-size: 0.8rem; 16 | margin-top: 0.5rem; 17 | text-align: right; 18 | } 19 | 20 | footer.swagger-ui { 21 | box-shadow: inset 1px 2px 0 rgba(0,0,0,.15); 22 | font-size: 0.7rem; 23 | margin: 2rem 0 1rem; 24 | padding-top: 1rem; 25 | text-align: right; 26 | } 27 | 28 | -------------------------------------------------------------------------------- /rest_framework_swagger/static/rest_framework_swagger/bundles/app.bundle.js: -------------------------------------------------------------------------------- 1 | !function(e){function n(n){for(var t,a,u=n[0],c=n[1],i=n[2],d=0,p=[];d 5 | 6 | 7 | Swagger UI 8 | 9 | 10 | 11 | {% block extra_styles %} 12 | {# -- Add any additional CSS scripts here -- #} 13 | {% endblock %} 14 | 15 | 16 | 17 |
18 |
19 |
20 |
21 | 22 | Swagger Logo 23 | swagger 24 | 25 |
26 | {% if USE_SESSION_AUTH %} 27 | {% if request.user.is_authenticated %} 28 | {% trans "Logout" %} 29 | {% else %} 30 | {% trans "Session Login" %} 31 | {% endif %} 32 | {% endif %} 33 |
34 |
35 |
36 |
37 | {% if USE_SESSION_AUTH %} 38 |
39 | {% block user_context_message %} 40 | {% if request.user.is_authenticated %} 41 | {% trans "You are logged in as: " %}{{ request.user }} 42 | {% else %} 43 | {% trans "Viewing as an anonymous user" %} 44 | {% endif %} 45 | {% endblock %} 46 |
47 | {% endif %} 48 |
49 | 50 |
51 | {% csrf_token %} 52 | 53 | 58 | 59 | 63 | 64 | 65 | {% block extra_scripts %} 66 | {# -- Add any additional scripts here -- #} 67 | {% endblock %} 68 | 69 | 70 | 71 | -------------------------------------------------------------------------------- /rest_framework_swagger/views.py: -------------------------------------------------------------------------------- 1 | from rest_framework import exceptions 2 | from rest_framework.permissions import AllowAny 3 | from rest_framework.renderers import CoreJSONRenderer 4 | from rest_framework.response import Response 5 | from rest_framework.schemas import SchemaGenerator 6 | from rest_framework.views import APIView 7 | 8 | from . import renderers 9 | 10 | 11 | def get_swagger_view(title=None, url=None, patterns=None, urlconf=None): 12 | """ 13 | Returns schema view which renders Swagger/OpenAPI. 14 | """ 15 | class SwaggerSchemaView(APIView): 16 | _ignore_model_permissions = True 17 | exclude_from_schema = True 18 | permission_classes = [AllowAny] 19 | renderer_classes = [ 20 | CoreJSONRenderer, 21 | renderers.OpenAPIRenderer, 22 | renderers.SwaggerUIRenderer 23 | ] 24 | 25 | def get(self, request): 26 | generator = SchemaGenerator( 27 | title=title, 28 | url=url, 29 | patterns=patterns, 30 | urlconf=urlconf 31 | ) 32 | schema = generator.get_schema(request=request) 33 | 34 | if not schema: 35 | raise exceptions.ValidationError( 36 | 'The schema generator did not return a schema Document' 37 | ) 38 | 39 | return Response(schema) 40 | 41 | return SwaggerSchemaView.as_view() 42 | -------------------------------------------------------------------------------- /run_example.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | docker build -t django-rest-swagger-example . 3 | docker run --rm -p 8000:8000 -v $(pwd):/code -ti django-rest-swagger-example 4 | -------------------------------------------------------------------------------- /runtests.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import os 3 | import sys 4 | 5 | import django 6 | from django.conf import settings 7 | from django.test.utils import get_runner 8 | 9 | if __name__ == "__main__": 10 | os.environ['DJANGO_SETTINGS_MODULE'] = 'tests.settings' 11 | django.setup() 12 | TestRunner = get_runner(settings) 13 | test_runner = TestRunner() 14 | failures = test_runner.run_tests(["tests"]) 15 | sys.exit(bool(failures)) 16 | -------------------------------------------------------------------------------- /runtime.txt: -------------------------------------------------------------------------------- 1 | python-3.6.0 2 | -------------------------------------------------------------------------------- /setup.cfg: -------------------------------------------------------------------------------- 1 | [wheel] 2 | universal = 1 3 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | import os 3 | import sys 4 | import shutil 5 | from setuptools import setup 6 | from rest_framework_swagger import __version__ as VERSION 7 | 8 | if sys.argv[-1] == 'publish': 9 | if os.system("wheel version"): 10 | print("wheel not installed.\nUse `pip install wheel`.\nExiting.") 11 | sys.exit() 12 | if os.system("pip freeze | grep twine"): 13 | print("twine not installed.\nUse `pip install twine`.\nExiting.") 14 | sys.exit() 15 | os.system("python setup.py sdist bdist_wheel") 16 | os.system("twine upload -r pypi dist/*") 17 | print("You probably want to also tag the version now:") 18 | print(" git tag -a %s -m 'version %s'" % (VERSION, VERSION)) 19 | print(" git push --tags") 20 | shutil.rmtree('dist') 21 | shutil.rmtree('build') 22 | shutil.rmtree('django_rest_swagger.egg-info') 23 | sys.exit() 24 | 25 | README = """ 26 | Django REST Swagger 27 | 28 | An API documentation generator for Swagger UI and Django REST Framework. 29 | 30 | Installation 31 | From pip: 32 | 33 | pip install django-rest-swagger 34 | 35 | Project @ https://github.com/marcgibbons/django-rest-swagger 36 | Docs @ https://django-rest-swagger.readthedocs.io/ 37 | """ 38 | 39 | # allow setup.py to be run from any path 40 | os.chdir(os.path.normpath(os.path.join(os.path.abspath(__file__), os.pardir))) 41 | 42 | setup( 43 | name='django-rest-swagger', 44 | version=VERSION, 45 | install_requires=[ 46 | 'coreapi>=2.3.0', 47 | 'openapi-codec>=1.3.1', 48 | 'djangorestframework>=3.5.4', 49 | 'Django>=1.8', 50 | 'simplejson' 51 | ], 52 | packages=['rest_framework_swagger'], 53 | include_package_data=True, 54 | license='FreeBSD License', 55 | description='Swagger UI for Django REST Framework 3.5+', 56 | long_description=README, 57 | test_suite='tests', 58 | author='Marc Gibbons', 59 | author_email='marc_gibbons@rogers.com', 60 | url='https://github.com/marcgibbons/django-rest-swagger', 61 | classifiers=[ 62 | 'Environment :: Web Environment', 63 | 'Framework :: Django', 64 | 'Framework :: Django :: 1.8', 65 | 'Framework :: Django :: 1.9', 66 | 'Framework :: Django :: 1.10', 67 | 'Framework :: Django :: 1.11', 68 | 'Framework :: Django :: 2.0', 69 | 'Framework :: Django :: 2.1', 70 | 'Intended Audience :: Developers', 71 | 'License :: OSI Approved :: BSD License', 72 | 'Operating System :: OS Independent', 73 | 'Programming Language :: Python', 74 | 'Programming Language :: Python :: 2', 75 | 'Programming Language :: Python :: 3', 76 | 'Programming Language :: Python :: 2.7', 77 | 'Programming Language :: Python :: 3.5', 78 | 'Programming Language :: Python :: 3.6', 79 | 'Topic :: Internet :: WWW/HTTP', 80 | 'Topic :: Internet :: WWW/HTTP :: Dynamic Content', 81 | ], 82 | zip_safe=False 83 | ) 84 | -------------------------------------------------------------------------------- /tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bestdev322/django-rest-swagger/b69bc2dd7f9193fa5a8c7d130d5d0fd0f8538292/tests/__init__.py -------------------------------------------------------------------------------- /tests/compat/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bestdev322/django-rest-swagger/b69bc2dd7f9193fa5a8c7d130d5d0fd0f8538292/tests/compat/__init__.py -------------------------------------------------------------------------------- /tests/compat/mock.py: -------------------------------------------------------------------------------- 1 | # pylint: disable=W0614,W0401 2 | from __future__ import absolute_import 3 | 4 | try: 5 | from unittest.mock import * 6 | except ImportError: 7 | from mock import * 8 | -------------------------------------------------------------------------------- /tests/renderers/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bestdev322/django-rest-swagger/b69bc2dd7f9193fa5a8c7d130d5d0fd0f8538292/tests/renderers/__init__.py -------------------------------------------------------------------------------- /tests/renderers/test_openapi_renderer.py: -------------------------------------------------------------------------------- 1 | import coreapi 2 | from coreapi.compat import force_bytes 3 | from django.test import TestCase 4 | import simplejson as json 5 | 6 | from rest_framework_swagger import renderers 7 | from ..compat.mock import MagicMock, patch 8 | 9 | 10 | class TestOpenAPICodec(TestCase): 11 | def setUp(self): 12 | self.sut = renderers.OpenAPICodec().encode 13 | 14 | def test_encode_without_document_instance_raises_assertion_error(self): 15 | """ 16 | Given that the data is not a CoreAPI Document instance, 17 | an assertion error should be raised. 18 | """ 19 | with self.assertRaises(TypeError) as cx: 20 | data = MagicMock() 21 | self.sut(data) 22 | 23 | expected = 'Expected a `coreapi.Document` instance' 24 | self.assertEqual(expected, str(cx.exception)) 25 | 26 | def test_encode_generates_swagger_object_when_given_valid_document(self): 27 | expected = {'fizz': 'buzz'} 28 | with patch( 29 | 'rest_framework_swagger.renderers.generate_swagger_object', 30 | return_value={'fizz': 'buzz'} 31 | ): 32 | result = self.sut(coreapi.Document()) 33 | 34 | self.assertEqual(force_bytes(json.dumps(expected)), result) 35 | 36 | def test_encode_adds_extra_data_provided_to_swagger_object(self): 37 | expected = {'foo': 'bar'} 38 | with patch( 39 | 'rest_framework_swagger.renderers.generate_swagger_object', 40 | return_value={} 41 | ): 42 | result = self.sut(coreapi.Document(), **expected) 43 | 44 | self.assertEqual(force_bytes(json.dumps(expected)), result) 45 | 46 | 47 | class TestOpenAPIRenderer(TestCase): 48 | def setUp(self): 49 | self.sut = renderers.OpenAPIRenderer() 50 | 51 | def test_media_type(self): 52 | self.assertEqual( 53 | 'application/openapi+json', 54 | self.sut.media_type 55 | ) 56 | 57 | def test_charset(self): 58 | self.assertIsNone(self.sut.charset) 59 | 60 | def test_format(self): 61 | self.assertEqual('openapi', self.sut.format) 62 | 63 | @patch('rest_framework_swagger.renderers.OpenAPICodec.encode') 64 | def test_render_encodes_customizations(self, encode_mock): 65 | data = coreapi.Document() 66 | renderer_context = { 67 | 'request': MagicMock(), 68 | 'response': MagicMock(status_code=200) 69 | } 70 | with patch.object(self.sut, 'get_customizations') as mock: 71 | self.sut.render(data, renderer_context=renderer_context) 72 | 73 | encode_mock.assert_called_once_with(data, **mock.return_value) 74 | 75 | def test_render_if_response_is_not_200(self): 76 | """ 77 | Given the response returned in the renderer_context has a status 78 | code other than 200, the data should be dumped. 79 | """ 80 | data = {'error': 'fizz buzz'} 81 | renderer_context = {'response': MagicMock(status_code=403)} 82 | result = self.sut.render(data, renderer_context=renderer_context) 83 | expected = renderers.JSONRenderer().render(data) 84 | 85 | self.assertEqual(expected, result) 86 | 87 | 88 | class TestGetCustomizations(TestCase): 89 | def setUp(self): 90 | self.sut = renderers.OpenAPIRenderer().get_customizations 91 | 92 | settings_patcher = patch('rest_framework_swagger.renderers.settings') 93 | self.swagger_settings = settings_patcher.start() 94 | self.addCleanup(settings_patcher.stop) 95 | 96 | def test_security_definitions_included_when_defined(self): 97 | self.swagger_settings.SECURITY_DEFINITIONS = {'foo': 'bar'} 98 | expected = { 99 | 'securityDefinitions': self.swagger_settings.SECURITY_DEFINITIONS 100 | } 101 | self.assertDictContainsSubset(expected, self.sut()) 102 | 103 | def test_security_definitions_not_present_when_none(self): 104 | self.swagger_settings.SECURITY_DEFINITIONS = None 105 | self.assertNotIn('securityDefinitions', self.sut()) 106 | -------------------------------------------------------------------------------- /tests/renderers/test_swagger.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | import simplejson as json 3 | 4 | from rest_framework_swagger.renderers import SwaggerUIRenderer 5 | from ..compat.mock import patch, MagicMock 6 | 7 | 8 | class TestSwaggerUIRenderer(TestCase): 9 | def setUp(self): 10 | self.sut = SwaggerUIRenderer() 11 | self.renderer_context = {'request': MagicMock()} 12 | 13 | swagger_settings_patcher = patch( 14 | 'rest_framework_swagger.renderers.settings', 15 | ) 16 | self.swagger_settings = swagger_settings_patcher.start() 17 | self.addCleanup(swagger_settings_patcher.stop) 18 | 19 | openapi_patcher = patch( 20 | 'rest_framework_swagger.renderers.OpenAPIRenderer' 21 | ) 22 | self.openapi_mock = openapi_patcher.start() 23 | self.addCleanup(openapi_patcher.stop) 24 | 25 | def test_media_type(self): 26 | self.assertEqual('text/html', self.sut.media_type) 27 | 28 | def test_format(self): 29 | self.assertEqual('swagger', self.sut.format) 30 | 31 | def test_template(self): 32 | self.assertEqual( 33 | 'rest_framework_swagger/index.html', 34 | self.sut.template 35 | ) 36 | 37 | def test_charset(self): 38 | self.assertEqual('utf-8', self.sut.charset) 39 | 40 | @patch('rest_framework_swagger.renderers.render') 41 | def test_render(self, render_mock): 42 | data = MagicMock() 43 | with patch.object(self.sut, 'set_context') as context_mock: 44 | self.sut.render( 45 | data=data, 46 | accepted_media_type=None, 47 | renderer_context=self.renderer_context 48 | ) 49 | 50 | context_mock.assert_called_once_with(data, self.renderer_context) 51 | render_mock.assert_called_once_with( 52 | self.renderer_context['request'], 53 | self.sut.template, 54 | self.renderer_context 55 | ) 56 | 57 | def test_set_context_use_session_auth(self): 58 | data = {} 59 | self.sut.set_context(data, self.renderer_context) 60 | 61 | self.assertEqual( 62 | self.renderer_context['USE_SESSION_AUTH'], 63 | self.swagger_settings.USE_SESSION_AUTH 64 | ) 65 | 66 | def test_set_context_sets_auth_urls(self): 67 | data = MagicMock() 68 | urls = {'fizz': 'buzz'} 69 | with patch.object(self.sut, 'get_auth_urls', return_value=urls): 70 | self.sut.set_context(data, self.renderer_context) 71 | 72 | self.assertDictContainsSubset(urls, self.renderer_context) 73 | 74 | def test_set_context_sets_ui_settings(self): 75 | data = MagicMock() 76 | with patch.object(self.sut, 'get_ui_settings') as mock: 77 | mock.return_value = {'foo': 'bar'} 78 | self.sut.set_context(data, self.renderer_context) 79 | 80 | self.assertEqual( 81 | json.dumps(mock.return_value), 82 | self.renderer_context['drs_settings'] 83 | ) 84 | 85 | def test_openapi_spec_is_added_to_context(self): 86 | data = MagicMock() 87 | self.sut.set_context(data, self.renderer_context) 88 | 89 | openapi_render = self.openapi_mock.return_value.render 90 | openapi_render.assert_called_once_with( 91 | data=data, 92 | renderer_context=self.renderer_context 93 | ) 94 | 95 | self.assertEqual( 96 | openapi_render.return_value.decode.return_value, 97 | self.renderer_context['spec'] 98 | ) 99 | 100 | def test_get_auth_urls(self): 101 | self.swagger_settings.LOGIN_URL = '/my-login' 102 | self.swagger_settings.LOGOUT_URL = '/my-logout' 103 | result = self.sut.get_auth_urls() 104 | 105 | self.assertDictEqual( 106 | { 107 | 'LOGIN_URL': self.swagger_settings.LOGIN_URL, 108 | 'LOGOUT_URL': self.swagger_settings.LOGOUT_URL, 109 | }, 110 | result 111 | ) 112 | 113 | def test_get_auth_urls_when_none(self): 114 | self.swagger_settings.LOGIN_URL = None 115 | self.swagger_settings.LOGOUT_URL = None 116 | 117 | self.assertEqual({}, self.sut.get_auth_urls()) 118 | 119 | def test_get_ui_settings_without_validator_url(self): 120 | expected = { 121 | 'apisSorter': self.swagger_settings.APIS_SORTER, 122 | 'docExpansion': self.swagger_settings.DOC_EXPANSION, 123 | 'jsonEditor': self.swagger_settings.JSON_EDITOR, 124 | 'operationsSorter': self.swagger_settings.OPERATIONS_SORTER, 125 | 'showRequestHeaders': self.swagger_settings.SHOW_REQUEST_HEADERS, 126 | 'supportedSubmitMethods': 127 | self.swagger_settings.SUPPORTED_SUBMIT_METHODS, 128 | 'validatorUrl': self.swagger_settings.VALIDATOR_URL, 129 | 'acceptHeaderVersion': self.swagger_settings.ACCEPT_HEADER_VERSION, 130 | 'customHeaders': self.swagger_settings.CUSTOM_HEADERS 131 | } 132 | result = self.sut.get_ui_settings() 133 | 134 | self.assertDictEqual(expected, result) 135 | 136 | def test_validator_url_none_when_set(self): 137 | self.swagger_settings.VALIDATOR_URL = None 138 | result = self.sut.get_ui_settings() 139 | 140 | self.assertDictContainsSubset({'validatorUrl': None}, result) 141 | 142 | def test_validator_url_not_present_when_empty_string(self): 143 | """ 144 | Given the validator URL is unspecified (empty string, not null), 145 | the validatorUrl should not be present. SwaggerUI will use 146 | swagger.io as the default. 147 | """ 148 | self.swagger_settings.VALIDATOR_URL = '' 149 | result = self.sut.get_ui_settings() 150 | 151 | self.assertNotIn('validatorUrl', result) 152 | -------------------------------------------------------------------------------- /tests/settings.py: -------------------------------------------------------------------------------- 1 | SECRET_KEY = 'fake-key' 2 | INSTALLED_APPS = [ 3 | 'django.contrib.contenttypes', 4 | 'django.contrib.auth', 5 | 'tests', 6 | ] 7 | ROOT_URLCONF = [] 8 | DATABASES = {'default': {'ENGINE': 'django.db.backends.sqlite3'}} 9 | -------------------------------------------------------------------------------- /tests/test_settings.py: -------------------------------------------------------------------------------- 1 | from django.test import override_settings, TestCase 2 | from rest_framework_swagger import settings 3 | 4 | 5 | class TestSettings(TestCase): 6 | def test_import_string(self): 7 | self.assertEqual([], settings.IMPORT_STRINGS) 8 | 9 | @override_settings(SWAGGER_SETTINGS={'SECURITY_DEFINITIONS': None}) 10 | def test_settings_when_none(self): 11 | self.assertIsNone(settings.swagger_settings.SECURITY_DEFINITIONS) 12 | 13 | 14 | class TestDefaults(TestCase): 15 | def setUp(self): 16 | self.sut = settings.swagger_settings 17 | 18 | @override_settings(LOGIN_URL='fizz') 19 | def test_login_url(self): 20 | self.assertEqual('fizz', self.sut.LOGIN_URL) 21 | 22 | @override_settings(LOGOUT_URL='buzz') 23 | def test_logout_url(self): 24 | self.assertEqual('buzz', self.sut.LOGOUT_URL) 25 | 26 | def test_use_session_auth(self): 27 | self.assertIs(True, self.sut.USE_SESSION_AUTH) 28 | 29 | def test_security_definitions(self): 30 | self.assertDictEqual( 31 | {'basic': {'type': 'basic'}}, 32 | self.sut.SECURITY_DEFINITIONS 33 | ) 34 | 35 | def test_operations_sorter(self): 36 | self.assertIsNone(self.sut.OPERATIONS_SORTER) 37 | 38 | def test_show_request_headers(self): 39 | self.assertIs(False, self.sut.SHOW_REQUEST_HEADERS) 40 | 41 | def test_validator_url(self): 42 | self.assertEqual('', self.sut.VALIDATOR_URL) 43 | 44 | def test_json_editor(self): 45 | self.assertIs(False, self.sut.JSON_EDITOR) 46 | 47 | def test_doc_expansion(self): 48 | self.assertIsNone(self.sut.DOC_EXPANSION) 49 | -------------------------------------------------------------------------------- /tests/test_views.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | from rest_framework.permissions import AllowAny 3 | from rest_framework.renderers import CoreJSONRenderer 4 | from rest_framework.request import Request 5 | from rest_framework.test import APIRequestFactory 6 | 7 | from rest_framework_swagger import renderers 8 | from rest_framework_swagger.views import get_swagger_view 9 | 10 | from .compat.mock import patch 11 | 12 | 13 | class TestGetSwaggerView(TestCase): 14 | def setUp(self): 15 | self.sut = get_swagger_view 16 | self.factory = APIRequestFactory() 17 | self.view_class = self.sut().cls 18 | 19 | def test_title_and_urlpassed_to_schema_generator(self): 20 | title = 'Vandelay' 21 | url = 'https://github.com/marcgibbons/django-rest-swagger' 22 | urlconf = 'fizz' 23 | patterns = [] 24 | view = self.sut( 25 | title=title, 26 | url=url, 27 | patterns=patterns, 28 | urlconf=urlconf 29 | ) 30 | 31 | with patch('rest_framework_swagger.views.SchemaGenerator') as mock: 32 | request = self.factory.get('/') 33 | view(request=request) 34 | 35 | mock.assert_called_once_with( 36 | title=title, 37 | url=url, 38 | patterns=patterns, 39 | urlconf=urlconf 40 | ) 41 | 42 | def test_ignore_model_permissions_true(self): 43 | self.assertTrue(self.view_class._ignore_model_permissions) 44 | 45 | def test_exclude_from_schema(self): 46 | self.assertTrue(self.view_class.exclude_from_schema) 47 | 48 | def test_renderer_classes(self): 49 | self.assertListEqual( 50 | [ 51 | CoreJSONRenderer, 52 | renderers.OpenAPIRenderer, 53 | renderers.SwaggerUIRenderer 54 | ], 55 | self.view_class.renderer_classes 56 | ) 57 | 58 | def test_permission_class(self): 59 | self.assertListEqual( 60 | [AllowAny], 61 | self.view_class.permission_classes 62 | ) 63 | 64 | def test_return_400_if_schema_is_none(self): 65 | with patch('rest_framework_swagger.views.SchemaGenerator') as mock: 66 | mock.return_value.get_schema.return_value = None 67 | request = self.factory.get('/') 68 | response = self.sut()(request=request) 69 | 70 | self.assertEqual(400, response.status_code) 71 | self.assertEqual( 72 | ['The schema generator did not return a schema Document'], 73 | response.data 74 | ) 75 | 76 | def test_response_is_result_of_schema_generator(self): 77 | expected = 'My amazing schema' 78 | with patch('rest_framework_swagger.views.SchemaGenerator') as mock: 79 | mock.return_value.get_schema.return_value = expected 80 | request = self.factory.get('/') 81 | response = self.sut()(request=request) 82 | 83 | self.assertEqual(200, response.status_code) 84 | self.assertEqual(expected, response.data) 85 | 86 | def test_schema_generator_instantiated_with_request(self): 87 | with patch('rest_framework_swagger.views.SchemaGenerator') as mock: 88 | request = self.factory.get('/') 89 | self.sut()(request=request) 90 | 91 | call_args = mock.return_value.get_schema.call_args[1] 92 | self.assertIn('request', call_args) 93 | self.assertIsInstance(call_args['request'], Request) 94 | -------------------------------------------------------------------------------- /tox.ini: -------------------------------------------------------------------------------- 1 | [tox] 2 | skipsdist=True 3 | envlist = 4 | latest 5 | {py27,py36}-django{18,19,110,111}-drf{35,36} 6 | {py27,py36}-django{110,111}-drf{37,38} 7 | {py36}-django{2}-drf{37,38} 8 | {py36}-django{21}-drf{39} 9 | lint 10 | 11 | [testenv] 12 | commands = ./runtests.py 13 | deps = 14 | coreapi 15 | coverage 16 | mock 17 | openapi-codec 18 | simplejson 19 | drf35: djangorestframework>=3.5.3,<3.6 20 | drf36: djangorestframework>=3.6.0,<3.7 21 | drf37: djangorestframework>=3.7.0,<3.8 22 | drf38: djangorestframework>=3.8.0,<3.9 23 | drf39: djangorestframework>=3.9.0,<3.10 24 | django18: Django>=1.8,<1.9 25 | django19: Django>=1.9,<1.10 26 | django110: Django>=1.10,<1.11 27 | django111: Django>=1.11,<2.0 28 | django2: Django>=2.0,<2.1 29 | django21: Django>=2.1,<2.2 30 | 31 | [testenv:latest] 32 | commands = coverage run runtests.py 33 | pip_pre = True 34 | deps = 35 | Django 36 | coreapi 37 | openapi-codec 38 | simplejson 39 | coverage 40 | djangorestframework 41 | 42 | 43 | [testenv:lint] 44 | commands = pylint rest_framework_swagger tests 45 | deps = -rrequirements.txt 46 | --------------------------------------------------------------------------------