From dba2beb05f078b38ed84e0d8724e8f7c63cc68c0 Mon Sep 17 00:00:00 2001
From: Dan Schien <dschien@gmail.com>
Date: Fri, 20 May 2016 08:59:01 +0100
Subject: [PATCH 1/2] interpret drfdocs_exclude field

---
 rest_framework_docs/api_docs.py     |  3 ++-
 rest_framework_docs/api_endpoint.py | 15 +++++++--------
 tests/tests.py                      |  5 ++---
 tests/urls.py                       |  1 +
 tests/views.py                      | 16 ++++++++--------
 5 files changed, 20 insertions(+), 20 deletions(-)

diff --git a/rest_framework_docs/api_docs.py b/rest_framework_docs/api_docs.py
index c51c205..ce53c11 100644
--- a/rest_framework_docs/api_docs.py
+++ b/rest_framework_docs/api_docs.py
@@ -27,7 +27,8 @@ def get_all_view_names(self, urlpatterns, parent_pattern=None):
                 self.get_all_view_names(urlpatterns=pattern.url_patterns, parent_pattern=parent_pattern)
             elif isinstance(pattern, RegexURLPattern) and self._is_drf_view(pattern) and not self._is_format_endpoint(pattern):
                 api_endpoint = ApiEndpoint(pattern, parent_pattern)
-                self.endpoints.append(api_endpoint)
+                if not api_endpoint.exclude:
+                    self.endpoints.append(api_endpoint)
 
     def _is_drf_view(self, pattern):
         """
diff --git a/rest_framework_docs/api_endpoint.py b/rest_framework_docs/api_endpoint.py
index f37155c..895e510 100644
--- a/rest_framework_docs/api_endpoint.py
+++ b/rest_framework_docs/api_endpoint.py
@@ -5,7 +5,6 @@
 
 
 class ApiEndpoint(object):
-
     def __init__(self, pattern, parent_pattern=None):
         self.pattern = pattern
         self.callback = pattern.callback
@@ -19,6 +18,7 @@ def __init__(self, pattern, parent_pattern=None):
         self.fields = self.__get_serializer_fields__()
         self.fields_json = self.__get_serializer_fields_json__()
         self.permissions = self.__get_permissions_class__()
+        self.exclude = getattr(self.callback.cls, 'drfdocs_exclude', False)
 
     def __get_path__(self, parent_pattern):
         if parent_pattern:
@@ -42,17 +42,16 @@ def __get_serializer_fields__(self):
             serializer = self.callback.cls.serializer_class
             if hasattr(serializer, 'get_fields'):
                 try:
-                    fields = [{
-                        "name": key,
-                        "type": str(field.__class__.__name__),
-                        "required": field.required
-                    } for key, field in serializer().get_fields().items()]
+                    fields = [{"name": key,
+                               "type": str(field.__class__.__name__),
+                               "required": field.required
+                               } for key, field in serializer().get_fields().items()]
                 except KeyError as e:
                     self.errors = e
                     fields = []
 
-                # FIXME:
-                # Show more attibutes of `field`?
+                    # FIXME:
+                    # Show more attibutes of `field`?
 
         return fields
 
diff --git a/tests/tests.py b/tests/tests.py
index afb58d0..dab865c 100644
--- a/tests/tests.py
+++ b/tests/tests.py
@@ -4,7 +4,6 @@
 
 
 class DRFDocsViewTests(TestCase):
-
     SETTINGS_HIDE_DOCS = {
         'HIDE_DOCS': True  # Default: False
     }
@@ -13,7 +12,6 @@ def setUp(self):
         super(DRFDocsViewTests, self).setUp()
 
     def test_settings_module(self):
-
         settings = DRFSettings()
 
         self.assertEqual(settings.get_setting("HIDE_DOCS"), False)
@@ -33,7 +31,8 @@ def test_index_view_with_endpoints(self):
         self.assertEqual(response.context["endpoints"][0].name_parent, "accounts")
         self.assertEqual(response.context["endpoints"][0].allowed_methods, ['POST', 'OPTIONS'])
         self.assertEqual(response.context["endpoints"][0].path, "/accounts/login/")
-        self.assertEqual(response.context["endpoints"][0].docstring, "A view that allows users to login providing their username and password.")
+        self.assertEqual(response.context["endpoints"][0].docstring,
+                         "A view that allows users to login providing their username and password.")
         self.assertEqual(len(response.context["endpoints"][0].fields), 2)
         self.assertEqual(response.context["endpoints"][0].fields[0]["type"], "CharField")
         self.assertTrue(response.context["endpoints"][0].fields[0]["required"])
diff --git a/tests/urls.py b/tests/urls.py
index b226620..b0c90dd 100644
--- a/tests/urls.py
+++ b/tests/urls.py
@@ -13,6 +13,7 @@
     url(r'^user/profile/$', views.UserProfileView.as_view(), name="profile"),
 
     url(r'^test/$', views.TestView.as_view(), name="test-view"),
+    url(r'^exclude/$', views.ExcludedTestView.as_view(), name="test-exclude"),
 ]
 
 organisations_urls = [
diff --git a/tests/views.py b/tests/views.py
index c6987d0..6516931 100644
--- a/tests/views.py
+++ b/tests/views.py
@@ -19,11 +19,18 @@ class TestView(TemplateView):
     template_name = "a_test.html"
 
 
+class ExcludedTestView(APIView):
+    """
+    This view should not be included in DRF Docs.
+    """
+    drfdocs_exclude = True
+
+
 class LoginView(APIView):
     """
     A view that allows users to login providing their username and password.
     """
-
+    drfdocs_exclude = False
     throttle_classes = ()
     permission_classes = ()
     parser_classes = (parsers.FormParser, parsers.MultiPartParser, parsers.JSONParser,)
@@ -39,7 +46,6 @@ def post(self, request):
 
 
 class UserRegistrationView(generics.CreateAPIView):
-
     permission_classes = (AllowAny,)
     serializer_class = serializers.UserRegistrationSerializer
 
@@ -56,7 +62,6 @@ def get_object(self):
 
 
 class PasswordResetView(APIView):
-
     permission_classes = (AllowAny,)
     queryset = User.objects.all()
 
@@ -72,7 +77,6 @@ def post(self, request, *args, **kwargs):
 
 
 class PasswordResetConfirmView(APIView):
-
     permission_classes = (AllowAny,)
     serializer_class = serializers.ResetPasswordSerializer
 
@@ -84,12 +88,10 @@ def post(self, request, *args, **kwargs):
 
 
 class CreateOrganisationView(generics.CreateAPIView):
-
     serializer_class = serializers.CreateOrganisationSerializer
 
 
 class OrganisationMembersView(generics.ListAPIView):
-
     serializer_class = serializers.OrganisationMembersSerializer
 
     def get_queryset(self):
@@ -98,7 +100,6 @@ def get_queryset(self):
 
 
 class LeaveOrganisationView(generics.DestroyAPIView):
-
     def get_object(self):
         return Membership.objects.order_by('?').first()
 
@@ -109,5 +110,4 @@ def delete(self, request, *args, **kwargs):
 
 
 class OrganisationErroredView(generics.ListAPIView):
-
     serializer_class = serializers.OrganisationErroredSerializer

From 10171010acff501eb4bfdeb9a1838a2e11fae49b Mon Sep 17 00:00:00 2001
From: Dan Schien <dschien@gmail.com>
Date: Fri, 20 May 2016 12:33:13 +0100
Subject: [PATCH 2/2] render to markdown

---
 requirements.txt                                            | 1 +
 rest_framework_docs/templates/rest_framework_docs/home.html | 5 +++--
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/requirements.txt b/requirements.txt
index f449bbb..102d273 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -3,3 +3,4 @@ djangorestframework==3.3.2
 coverage==4.0.3
 flake8==2.5.1
 mkdocs==0.15.3
+django-markdown2==2.3.1
\ No newline at end of file
diff --git a/rest_framework_docs/templates/rest_framework_docs/home.html b/rest_framework_docs/templates/rest_framework_docs/home.html
index 76d783d..6e9f9d1 100644
--- a/rest_framework_docs/templates/rest_framework_docs/home.html
+++ b/rest_framework_docs/templates/rest_framework_docs/home.html
@@ -1,4 +1,5 @@
 {% extends "rest_framework_docs/docs.html" %}
+{% load md2 %}
 
 {% block apps_menu %}
 {% regroup endpoints by name_parent as endpoints_grouped %}
@@ -56,7 +57,7 @@ <h4 class="panel-title title">
         <div id="{{ endpoint.path|slugify }}" class="panel-collapse collapse" role="tabpanel">
           <div class="panel-body">
             {% if endpoint.docstring %}
-            <p class="lead">{{ endpoint.docstring }}</p>
+            <div class="lead">{{ endpoint.docstring | markdown:"code-friendly, code-color"}}</div>
             {% endif %}
 
             {% if endpoint.errors %}
@@ -71,7 +72,7 @@ <h4 class="panel-title title">
               {% endfor %}
               </ul>
             {% elif not endpoint.errors %}
-            <p>No fields.</p>
+            <!--<p>No fields.</p>-->
             {% endif %}
           </div>
         </div>