Skip to content

Commit 4018596

Browse files
author
Carlton Gibson
authored
Merge pull request carltongibson#553 from rpkilby/document-coreapi-caveats
Document schema generation caveats
2 parents 273875a + 8789d68 commit 4018596

File tree

1 file changed

+62
-2
lines changed

1 file changed

+62
-2
lines changed

docs/rest_framework.txt

Lines changed: 62 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,14 +98,74 @@ You may bypass creating a ``FilterSet`` by instead adding ``filter_fields`` to y
9898
fields = ('category', 'in_stock')
9999

100100

101+
Schema Generation with Core API
102+
-------------------------------
103+
104+
The backend class integrates with DRF's schema generation by implementing ``get_schema_fields()``. This is automatically enabled when Core API is installed. Schema generation usually functions seamlessly, however the implementation does expect to invoke the view's ``get_queryset()`` method. There is a caveat in that views are artificially constructed during schema generation, so the ``args`` and ``kwargs`` attributes will be empty. If you depend on arguments parsed from the URL, you will need to handle their absence in ``get_queryset()``.
105+
106+
For example, your get queryset method may look like this:
107+
108+
.. code-block:: python
109+
110+
class IssueViewSet(views.ModelViewSet):
111+
queryset = models.Issue.objects.all()
112+
113+
def get_project(self):
114+
return models.Project.objects.get(pk=self.kwargs['project_id'])
115+
116+
def get_queryset(self):
117+
project = self.get_project()
118+
119+
return self.queryset \
120+
.filter(project=project) \
121+
.filter(author=self.request.user)
122+
123+
This could be rewritten like so:
124+
125+
.. code-block:: python
126+
127+
class IssueViewSet(views.ModelViewSet):
128+
queryset = models.Issue.objects.all()
129+
130+
def get_project(self):
131+
try:
132+
return models.Project.objects.get(pk=self.kwargs['project_id'])
133+
except models.Project.DoesNotExist:
134+
return None
135+
136+
def get_queryset(self):
137+
project = self.get_project()
138+
139+
if project is None:
140+
return self.queryset.none()
141+
142+
return self.queryset \
143+
.filter(project=project) \
144+
.filter(author=self.request.user)
145+
146+
Or more simply as:
147+
148+
.. code-block:: python
149+
150+
class IssueViewSet(views.ModelViewSet):
151+
queryset = models.Issue.objects.all()
152+
153+
def get_queryset(self):
154+
# project_id may be None
155+
return self.queryset \
156+
.filter(project_id=self.kwargs.get('project_id')) \
157+
.filter(author=self.request.user)
158+
159+
101160
Crispy Forms
102161
------------
103-
If you are using DRF's browsable API or admin API you may also want to install `django-crispy-forms`, which will enhance the presentation of the filter forms in HTML views, by allowing them to render Bootstrap 3 HTML. Note that this isn't actively supported, although pull requests for bug fixes are welcome.
162+
163+
If you are using DRF's browsable API or admin API you may also want to install ``django-crispy-forms``, which will enhance the presentation of the filter forms in HTML views, by allowing them to render Bootstrap 3 HTML. Note that this isn't actively supported, although pull requests for bug fixes are welcome.
104164

105165
.. code-block:: bash
106166

107167
pip install django-crispy-forms
108168

109-
With crispy forms installed and added to Django's `INSTALLED_APPS`, the browsable API will present a filtering control for `DjangoFilterBackend`, like so:
169+
With crispy forms installed and added to Django's ``INSTALLED_APPS``, the browsable API will present a filtering control for ``DjangoFilterBackend``, like so:
110170

111171
.. image:: img/form.png

0 commit comments

Comments
 (0)