Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
D
django-rest-framework
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
edx
django-rest-framework
Commits
5db900c6
Commit
5db900c6
authored
Aug 21, 2015
by
Tom Christie
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
First pass at HTML rendering for filters
parent
f601c6c1
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
122 additions
and
1 deletions
+122
-1
rest_framework/filters.py
+51
-1
rest_framework/renderers.py
+21
-0
rest_framework/static/rest_framework/css/default.css
+8
-0
rest_framework/templates/rest_framework/base.html
+12
-0
rest_framework/templates/rest_framework/filters/base.html
+16
-0
rest_framework/templates/rest_framework/filters/django_filter.html
+4
-0
rest_framework/templates/rest_framework/filters/ordering.html
+10
-0
No files found.
rest_framework/filters.py
View file @
5db900c6
...
...
@@ -9,6 +9,7 @@ from functools import reduce
from
django.core.exceptions
import
ImproperlyConfigured
from
django.db
import
models
from
django.template
import
Context
,
Template
,
loader
from
django.utils
import
six
from
rest_framework.compat
import
(
...
...
@@ -36,6 +37,7 @@ class DjangoFilterBackend(BaseFilterBackend):
A filter backend that uses django-filter.
"""
default_filter_set
=
FilterSet
template
=
'rest_framework/filters/django_filter.html'
def
__init__
(
self
):
assert
django_filters
,
'Using DjangoFilterBackend, but django-filter is not installed'
...
...
@@ -57,11 +59,33 @@ class DjangoFilterBackend(BaseFilterBackend):
return
filter_class
if
filter_fields
:
from
crispy_forms.helper
import
FormHelper
from
crispy_forms.layout
import
Field
,
Fieldset
,
Layout
,
Submit
class
AutoFilterSet
(
self
.
default_filter_set
):
class
Meta
:
model
=
queryset
.
model
fields
=
filter_fields
@property
def
form
(
self
):
self
.
_form
=
super
(
AutoFilterSet
,
self
)
.
form
for
field
in
self
.
_form
.
fields
.
values
():
field
.
help_text
=
None
layout_components
=
filter_fields
+
[
Submit
(
''
,
'Apply'
,
css_class
=
'btn-default'
),
]
helper
=
FormHelper
()
helper
.
form_method
=
'get'
helper
.
form_action
=
'.'
helper
.
template_pack
=
'bootstrap3'
helper
.
layout
=
Layout
(
*
layout_components
)
self
.
_form
.
helper
=
helper
return
self
.
_form
return
AutoFilterSet
return
None
...
...
@@ -74,6 +98,15 @@ class DjangoFilterBackend(BaseFilterBackend):
return
queryset
def
to_html
(
self
,
request
,
queryset
,
view
):
cls
=
self
.
get_filter_class
(
view
,
queryset
)
filter_instance
=
cls
(
request
.
query_params
,
queryset
=
queryset
)
context
=
Context
({
'filter'
:
filter_instance
})
template
=
loader
.
get_template
(
self
.
template
)
return
template
.
render
(
context
)
class
SearchFilter
(
BaseFilterBackend
):
# The URL query parameter used for the search.
...
...
@@ -127,6 +160,7 @@ class OrderingFilter(BaseFilterBackend):
# The URL query parameter used for the ordering.
ordering_param
=
api_settings
.
ORDERING_PARAM
ordering_fields
=
None
template
=
'rest_framework/filters/ordering.html'
def
get_ordering
(
self
,
request
,
queryset
,
view
):
"""
...
...
@@ -152,7 +186,7 @@ class OrderingFilter(BaseFilterBackend):
return
(
ordering
,)
return
ordering
def
remove_invalid_fields
(
self
,
queryset
,
fields
,
view
):
def
get_valid_fields
(
self
,
queryset
,
view
):
valid_fields
=
getattr
(
view
,
'ordering_fields'
,
self
.
ordering_fields
)
if
valid_fields
is
None
:
...
...
@@ -172,6 +206,10 @@ class OrderingFilter(BaseFilterBackend):
valid_fields
=
[
field
.
name
for
field
in
queryset
.
model
.
_meta
.
fields
]
valid_fields
+=
queryset
.
query
.
aggregates
.
keys
()
return
valid_fields
def
remove_invalid_fields
(
self
,
queryset
,
fields
,
view
):
valid_fields
=
self
.
get_valid_fields
(
queryset
,
view
)
return
[
term
for
term
in
fields
if
term
.
lstrip
(
'-'
)
in
valid_fields
]
def
filter_queryset
(
self
,
request
,
queryset
,
view
):
...
...
@@ -182,6 +220,18 @@ class OrderingFilter(BaseFilterBackend):
return
queryset
def
get_template_context
(
self
,
request
,
queryset
,
view
):
#default_tuple = self.get_default_ordering()
#default = None if default_tuple is None else default_tuple[0]
{
'options'
:
self
.
get_valid_fields
(
queryset
,
view
),
}
def
to_html
(
self
,
request
,
queryset
,
view
):
template
=
loader
.
get_template
(
self
.
template
)
context
=
Context
(
self
.
get_template_context
(
request
,
queryset
,
view
))
return
template
.
render
(
context
)
class
DjangoObjectPermissionsFilter
(
BaseFilterBackend
):
"""
...
...
rest_framework/renderers.py
View file @
5db900c6
...
...
@@ -374,6 +374,7 @@ class BrowsableAPIRenderer(BaseRenderer):
media_type
=
'text/html'
format
=
'api'
template
=
'rest_framework/api.html'
filter_template
=
'rest_framework/filters/base.html'
charset
=
'utf-8'
form_renderer_class
=
HTMLFormRenderer
...
...
@@ -600,6 +601,24 @@ class BrowsableAPIRenderer(BaseRenderer):
def
get_breadcrumbs
(
self
,
request
):
return
get_breadcrumbs
(
request
.
path
,
request
)
def
get_filter_form
(
self
,
view
,
request
):
if
not
hasattr
(
view
,
'get_queryset'
)
or
not
hasattr
(
view
,
'filter_backends'
):
return
queryset
=
view
.
get_queryset
()
elements
=
[]
for
backend
in
view
.
filter_backends
:
if
hasattr
(
backend
,
'to_html'
):
html
=
backend
()
.
to_html
(
request
,
queryset
,
view
)
elements
.
append
(
html
)
if
not
elements
:
return
template
=
loader
.
get_template
(
self
.
filter_template
)
context
=
Context
({
'elements'
:
elements
})
return
template
.
render
(
context
)
def
get_context
(
self
,
data
,
accepted_media_type
,
renderer_context
):
"""
Returns the context used to render.
...
...
@@ -647,6 +666,8 @@ class BrowsableAPIRenderer(BaseRenderer):
'delete_form'
:
self
.
get_rendered_html_form
(
data
,
view
,
'DELETE'
,
request
),
'options_form'
:
self
.
get_rendered_html_form
(
data
,
view
,
'OPTIONS'
,
request
),
'filter_form'
:
self
.
get_filter_form
(
view
,
request
),
'raw_data_put_form'
:
raw_data_put_form
,
'raw_data_post_form'
:
raw_data_post_form
,
'raw_data_patch_form'
:
raw_data_patch_form
,
...
...
rest_framework/static/rest_framework/css/default.css
View file @
5db900c6
...
...
@@ -73,3 +73,11 @@ pre {
border-bottom
:
none
;
padding-bottom
:
0px
;
}
#filtersModal
form
input
[
type
=
submit
]
{
width
:
auto
;
}
#filtersModal
.modal-body
h2
{
margin-top
:
0
}
rest_framework/templates/rest_framework/base.html
View file @
5db900c6
...
...
@@ -109,6 +109,13 @@
</form>
{% endif %}
{% if filter_form %}
<button
style=
"float: right; margin-right: 10px"
data-toggle=
"modal"
data-target=
"#filtersModal"
class=
"btn btn-default"
>
<span
class=
"glyphicon glyphicon-wrench"
aria-hidden=
"true"
></span>
Filters
</button>
{% endif %}
<div
class=
"content-main"
>
<div
class=
"page-header"
>
<h1>
{{ name }}
</h1>
...
...
@@ -242,6 +249,11 @@
<script
src=
"{% static "
rest_framework
/
js
/
prettify-min
.
js
"
%}"
></script>
<script
src=
"{% static "
rest_framework
/
js
/
default
.
js
"
%}"
></script>
{% endblock %}
{% if filter_form %}
{{ filter_form }}
{% endif %}
</body>
{% endblock %}
</html>
rest_framework/templates/rest_framework/filters/base.html
0 → 100644
View file @
5db900c6
<div
class=
"modal fade"
id=
"filtersModal"
tabindex=
"-1"
role=
"dialog"
aria-labelledby=
"filters"
aria-hidden=
"true"
>
<div
class=
"modal-dialog"
>
<div
class=
"modal-content"
>
<div
class=
"modal-header"
>
<button
type=
"button"
class=
"close"
data-dismiss=
"modal"
aria-label=
"Close"
><span
aria-hidden=
"true"
>
×
</span></button>
<h4
class=
"modal-title"
>
Filters
</h4>
</div>
<div
class=
"modal-body"
>
{% for element in elements %}
{% if not forloop.first %}
<hr/>
{% endif %}
{{ element }}
{% endfor %}
</div>
</div>
</div>
</div>
rest_framework/templates/rest_framework/filters/django_filter.html
0 → 100644
View file @
5db900c6
{% load crispy_forms_tags %}
<h2>
Field search
</h2>
{% crispy filter.form %}
rest_framework/templates/rest_framework/filters/ordering.html
0 → 100644
View file @
5db900c6
<h2>
Ordering
</h2>
<div
class=
"list-group"
>
<a
href=
"."
class=
"list-group-item active"
>
Most recently created
<span
class=
"glyphicon glyphicon-ok"
style=
"float: right"
aria-hidden=
"true"
></span>
</a>
<a
href=
"."
class=
"list-group-item"
>
Least recently created
</a>
<a
href=
"."
class=
"list-group-item"
>
Username ascending
</a>
<a
href=
"."
class=
"list-group-item"
>
Username descending
</a>
</div>
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment