diff --git a/assets/javascripts/templates/pages/about_tmpl.coffee b/assets/javascripts/templates/pages/about_tmpl.coffee
index 5fc27d3c..b2df2c21 100644
--- a/assets/javascripts/templates/pages/about_tmpl.coffee
+++ b/assets/javascripts/templates/pages/about_tmpl.coffee
@@ -231,6 +231,11 @@ credits = [
'Django Software Foundation and individual contributors',
'BSD',
'https://raw.githubusercontent.com/django/django/master/LICENSE'
+ ], [
+ 'Django REST Framework',
+ '2011-present Encode OSS Ltd.',
+ 'BSD',
+ 'https://raw.githubusercontent.com/encode/django-rest-framework/master/LICENSE.md'
], [
'Docker',
'2019 Docker, Inc.
Docker and the Docker logo are trademarks of Docker, Inc.',
diff --git a/assets/stylesheets/application.css.scss b/assets/stylesheets/application.css.scss
index 1d058ebe..22f539b7 100644
--- a/assets/stylesheets/application.css.scss
+++ b/assets/stylesheets/application.css.scss
@@ -72,6 +72,7 @@
'pages/lua',
'pages/mdn',
'pages/meteor',
+ 'pages/mkdocs',
'pages/modernizr',
'pages/moment',
'pages/nginx',
diff --git a/assets/stylesheets/pages/_mkdocs.scss b/assets/stylesheets/pages/_mkdocs.scss
new file mode 100644
index 00000000..e374474c
--- /dev/null
+++ b/assets/stylesheets/pages/_mkdocs.scss
@@ -0,0 +1,11 @@
+._mkdocs {
+ h2 { @extend %block-heading; }
+ h3 { @extend %block-label, %label-blue; }
+ h4 { @extend %block-label; }
+
+ blockquote { @extend %note; }
+
+ strong { font-weight: var(--bolderFontWeight); }
+
+ p > code, li > code { @extend %label; }
+}
diff --git a/lib/docs/filters/django_rest_framework/clean_html.rb b/lib/docs/filters/django_rest_framework/clean_html.rb
new file mode 100644
index 00000000..67c131bb
--- /dev/null
+++ b/lib/docs/filters/django_rest_framework/clean_html.rb
@@ -0,0 +1,30 @@
+module Docs
+ class DjangoRestFramework
+ class CleanHtmlFilter < Docs::Filter
+ def call
+ css('hr').remove
+ css('.badges').remove
+
+ css('pre').attr('data-language', 'python')
+
+ css('h1').remove_attribute('style')
+ css('.promo a').remove_attribute('style')
+
+ # Translate source files links to DevDocs links
+ links = Nokogiri::XML::Node.new('p', doc)
+ links['class'] = '_links'
+
+ css('a.github').each do |node|
+ span = node.at_css('span')
+ node.content = span.content
+ node['class'] = '_links-link'
+ links.add_child(node)
+ end
+
+ doc.add_child(links)
+
+ doc
+ end
+ end
+ end
+end
diff --git a/lib/docs/filters/django_rest_framework/entries.rb b/lib/docs/filters/django_rest_framework/entries.rb
new file mode 100644
index 00000000..d583af9e
--- /dev/null
+++ b/lib/docs/filters/django_rest_framework/entries.rb
@@ -0,0 +1,59 @@
+module Docs
+ class DjangoRestFramework
+ class EntriesFilter < Docs::EntriesFilter
+ def get_name
+ name = css('h1').first.content
+ name.slice! 'Tutorial '
+ name = '0: ' + name if name.include? 'Quickstart'
+ name
+ end
+
+ def get_type
+ case subpath
+ when /\Atutorial/
+ 'Tutorial'
+ when /\Aapi-guide/
+ 'API Guide'
+ end
+ end
+
+ def additional_entries
+ return [] if type == nil || type == 'Tutorial'
+
+ # Framework classes are provided in two different ways:
+ # - as H2's after H1 category titled:
+ accepted_headers = ['API Reference', 'API Guide']
+ # - as headers (1 or 2) with these endings:
+ endings = ['Validator', 'Field', 'View', 'Mixin', 'Default', 'Serializer']
+
+ # To avoid writing down all the endings
+ # and to ensure all entries in API categories are matched
+ # two different ways of finding them are used
+
+ entries = []
+
+ local_type = 'Ref: ' + name
+ in_category = false
+
+ css('h1, h2').each do |node|
+ # Third party category contains entries that could be matched (and shouldn't be)
+ break if node.content === 'Third party packages'
+
+ if in_category
+ if node.name === 'h1'
+ in_category = false
+ next
+ end
+ entries << [node.content, node['id'], local_type]
+ elsif accepted_headers.include? node.content
+ in_category = true
+ elsif endings.any? { |word| node.content.ends_with?(word) }
+ entries << [node.content, node['id'], local_type]
+ end
+ end
+
+ entries
+ end
+ end
+ end
+end
diff --git a/lib/docs/filters/mkdocs/clean_html.rb b/lib/docs/filters/mkdocs/clean_html.rb
new file mode 100644
index 00000000..2eef9cdc
--- /dev/null
+++ b/lib/docs/filters/mkdocs/clean_html.rb
@@ -0,0 +1,17 @@
+module Docs
+ class Mkdocs
+ class CleanHtmlFilter < Docs::Filter
+ def call
+ css('.toclink').each do |node|
+ node.parent.content = node.content
+ end
+
+ css('pre').each do |node|
+ node.content = node.at_css('code').content
+ end
+
+ at_css('#main-content')
+ end
+ end
+ end
+end
diff --git a/lib/docs/scrapers/mkdocs/django_rest_framework.rb b/lib/docs/scrapers/mkdocs/django_rest_framework.rb
new file mode 100644
index 00000000..db58eb8c
--- /dev/null
+++ b/lib/docs/scrapers/mkdocs/django_rest_framework.rb
@@ -0,0 +1,29 @@
+module Docs
+ class DjangoRestFramework < Mkdocs
+ self.name = 'Django REST Framework'
+ self.release = '3.9.3'
+ self.slug = 'django_rest_framework'
+ self.base_url = 'https://www.django-rest-framework.org/'
+ self.root_path = 'index.html'
+ self.links = {
+ home: 'https://www.django-rest-framework.org/',
+ code: 'https://github.com/encode/django-rest-framework'
+ }
+
+ html_filters.push 'django_rest_framework/clean_html', 'django_rest_framework/entries'
+
+ options[:skip_patterns] = [
+ /\Atopics\//,
+ /\Acommunity\//,
+ ]
+
+ options[:attribution] = <<-HTML
+ Copyright © 2011–present Encode OSS Ltd.
+ Licensed under the BSD License.
+ HTML
+
+ def get_latest_version(opts)
+ get_latest_github_release('encode', 'django-rest-framework', opts)
+ end
+ end
+end
diff --git a/lib/docs/scrapers/mkdocs/mkdocs.rb b/lib/docs/scrapers/mkdocs/mkdocs.rb
new file mode 100644
index 00000000..20559863
--- /dev/null
+++ b/lib/docs/scrapers/mkdocs/mkdocs.rb
@@ -0,0 +1,19 @@
+module Docs
+ class Mkdocs < UrlScraper
+ self.abstract = true
+ self.type = 'mkdocs'
+
+ html_filters.push 'mkdocs/clean_html'
+
+ private
+
+ def handle_response(response)
+ # Some scrapped urls don't have ending slash
+ # which leads to page duplication
+ if !response.url.path.ends_with?('/') && !response.url.path.ends_with?('index.html')
+ response.url.path << '/'
+ end
+ super
+ end
+ end
+end
diff --git a/public/icons/docs/django_rest_framework/16.png b/public/icons/docs/django_rest_framework/16.png
new file mode 100644
index 00000000..e2e33539
Binary files /dev/null and b/public/icons/docs/django_rest_framework/16.png differ
diff --git a/public/icons/docs/django_rest_framework/16@2x.png b/public/icons/docs/django_rest_framework/16@2x.png
new file mode 100644
index 00000000..e4ea76ba
Binary files /dev/null and b/public/icons/docs/django_rest_framework/16@2x.png differ
diff --git a/public/icons/docs/django_rest_framework/SOURCE b/public/icons/docs/django_rest_framework/SOURCE
new file mode 100644
index 00000000..96950eed
--- /dev/null
+++ b/public/icons/docs/django_rest_framework/SOURCE
@@ -0,0 +1 @@
+https://github.com/encode/django-rest-framework/blob/master/docs_theme/img/favicon.ico