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
c04cb514
Commit
c04cb514
authored
Feb 14, 2012
by
Sébastien Piquemal
Browse files
Options
Browse Files
Download
Plain Diff
merged with trunk
parents
821844bb
ba1e3b46
Show whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
219 additions
and
68 deletions
+219
-68
AUTHORS
+1
-0
CHANGELOG.rst
+3
-1
MANIFEST.in
+2
-2
README.rst
+6
-1
djangorestframework/mixins.py
+1
-1
djangorestframework/permissions.py
+50
-2
djangorestframework/response.py
+1
-1
djangorestframework/static/css/djangorestframework.css
+57
-0
djangorestframework/templates/api_login.html
+18
-28
djangorestframework/tests/mixins.py
+9
-0
examples/settings.py
+6
-7
examples/urls.py
+6
-3
setup.py
+59
-22
No files found.
AUTHORS
View file @
c04cb514
...
...
@@ -29,6 +29,7 @@ Benoit C <dzen>
Chris Pickett <bunchesofdonald>
Ben Timby <btimby>
Michele Lazzeri <michelelazzeri-nextage>
Camille Harang <mammique>
THANKS TO:
...
...
CHANGELOG.rst
View file @
c04cb514
...
...
@@ -4,11 +4,13 @@ Release Notes
development
-----------
*
Saner template variable autoescaping
.
*
Added DjangoModelPermissions class to support `django.contrib.auth` style permissions
.
* Use `staticfiles` for css files.
- Easier to override. Won't conflict with customised admin styles (eg grappelli)
* Drop implied 'pk' filter if last arg in urlconf is unnamed.
- Too magical. Explict is better than implicit.
* Saner template variable autoescaping.
* Tider setup.py
* Bugfixes:
- Bug with PerUserThrottling when user contains unicode chars.
...
...
MANIFEST.in
View file @
c04cb514
recursive-include djangorestframework/static *.ico *.txt
recursive-include djangorestframework/static *.ico *.txt
*.css
recursive-include djangorestframework/templates *.txt *.html
recursive-include examples .keep *.py *.txt
recursive-include docs *.py *.rst *.html *.txt
include AUTHORS LICENSE requirements.txt tox.ini
include AUTHORS LICENSE
CHANGELOG.rst
requirements.txt tox.ini
README.rst
View file @
c04cb514
Django REST framework
=====================
Django REST framework makes it easy to build well-connected, self-describing RESTful Web APIs.
**Django REST framework makes it easy to build well-connected, self-describing RESTful Web APIs.**
**Author:** Tom Christie. `Follow me on Twitter <https://twitter.com/_tomchristie>`_.
Overview
========
Features:
...
...
djangorestframework/mixins.py
View file @
c04cb514
...
...
@@ -499,7 +499,7 @@ class PaginatorMixin(object):
Constructs a url used for getting the next/previous urls
"""
url
=
URLObject
.
parse
(
self
.
request
.
get_full_path
())
url
=
url
.
add
_query_param
(
'page'
,
page_number
)
url
=
url
.
set
_query_param
(
'page'
,
page_number
)
limit
=
self
.
get_limit
()
if
limit
!=
self
.
limit
:
...
...
djangorestframework/permissions.py
View file @
c04cb514
...
...
@@ -20,6 +20,8 @@ __all__ = (
'PerResourceThrottling'
)
SAFE_METHODS
=
[
'GET'
,
'HEAD'
,
'OPTIONS'
]
_403_FORBIDDEN_RESPONSE
=
ImmediateResponse
(
{
'detail'
:
'You do not have permission to access this resource. '
+
...
...
@@ -84,8 +86,54 @@ class IsUserOrIsAnonReadOnly(BasePermission):
def
check_permission
(
self
,
user
):
if
(
not
user
.
is_authenticated
()
and
self
.
view
.
method
!=
'GET'
and
self
.
view
.
method
!=
'HEAD'
):
self
.
view
.
method
not
in
SAFE_METHODS
):
raise
_403_FORBIDDEN_RESPONSE
class
DjangoModelPermissions
(
BasePermission
):
"""
The request is authenticated using `django.contrib.auth` permissions.
See: https://docs.djangoproject.com/en/dev/topics/auth/#permissions
It ensures that the user is authenticated, and has the appropriate
`add`/`change`/`delete` permissions on the model.
This permission should only be used on views with a `ModelResource`.
"""
# Map methods into required permission codes.
# Override this if you need to also provide 'read' permissions,
# or if you want to provide custom permission codes.
perms_map
=
{
'GET'
:
[],
'OPTIONS'
:
[],
'HEAD'
:
[],
'POST'
:
[
'
%(app_label)
s.add_
%(model_name)
s'
],
'PUT'
:
[
'
%(app_label)
s.change_
%(model_name)
s'
],
'PATCH'
:
[
'
%(app_label)
s.change_
%(model_name)
s'
],
'DELETE'
:
[
'
%(app_label)
s.delete_
%(model_name)
s'
],
}
def
get_required_permissions
(
self
,
method
,
model_cls
):
"""
Given a model and an HTTP method, return the list of permission
codes that the user is required to have.
"""
kwargs
=
{
'app_label'
:
model_cls
.
_meta
.
app_label
,
'model_name'
:
model_cls
.
_meta
.
module_name
}
try
:
return
[
perm
%
kwargs
for
perm
in
self
.
perms_map
[
method
]]
except
KeyError
:
ErrorResponse
(
status
.
HTTP_405_METHOD_NOT_ALLOWED
)
def
check_permission
(
self
,
user
):
method
=
self
.
view
.
method
model_cls
=
self
.
view
.
resource
.
model
perms
=
self
.
get_required_permissions
(
method
,
model_cls
)
if
not
user
.
is_authenticated
or
not
user
.
has_perms
(
perms
):
raise
_403_FORBIDDEN_RESPONSE
...
...
djangorestframework/response.py
View file @
c04cb514
...
...
@@ -162,7 +162,7 @@ class Response(SimpleTemplateResponse):
return
self
.
renderers
[
0
]
class
ImmediateResponse
(
Response
,
Base
Exception
):
class
ImmediateResponse
(
Response
,
Exception
):
"""
A subclass of :class:`Response` used to abort the current request handling.
"""
...
...
djangorestframework/static/css/djangorestframework.css
View file @
c04cb514
...
...
@@ -1129,6 +1129,58 @@ fieldset.monospace textarea {
float
:
right
;
}
body
.login
{
background
:
#eee
;
}
.login
#container
{
background
:
white
;
border
:
1px
solid
#ccc
;
width
:
28em
;
min-width
:
300px
;
margin-left
:
auto
;
margin-right
:
auto
;
margin-top
:
100px
;
}
.login
#content-main
{
width
:
100%
;
}
.login
form
{
margin-top
:
1em
;
}
.login
.form-row
{
padding
:
4px
0
;
float
:
left
;
width
:
100%
;
}
.login
.form-row
label
{
float
:
left
;
width
:
9em
;
padding-right
:
0.5em
;
line-height
:
2em
;
text-align
:
right
;
font-size
:
1em
;
color
:
#333
;
}
.login
.form-row
#id_username
,
.login
.form-row
#id_password
{
width
:
14em
;
}
.login
span
.help
{
font-size
:
10px
;
display
:
block
;
}
.login
.submit-row
{
clear
:
both
;
padding
:
1em
0
0
9.4em
;
}
/* Overrides specific to REST framework */
#site-name
a
{
...
...
@@ -1147,6 +1199,11 @@ fieldset.monospace textarea {
}
/* Custom styles */
.version
{
font-size
:
8px
;
}
.form-row
{
border-bottom
:
0.25em
!important
;
}
djangorestframework/templates/api_login.html
View file @
c04cb514
{% load static %}
<html>
<head>
{% if ADMIN_MEDIA_PREFIX %}
<link
rel=
"stylesheet"
type=
"text/css"
href=
'{{ADMIN_MEDIA_PREFIX}}css/base.css'
/>
<link
rel=
"stylesheet"
type=
"text/css"
href=
'{{ADMIN_MEDIA_PREFIX}}css/forms.css'
/>
<link
rel=
"stylesheet"
type=
"text/css"
href=
'{{ADMIN_MEDIA_PREFIX}}css/login.css'
/>
{% else %}
<link
rel=
"stylesheet"
type=
"text/css"
href=
'{{STATIC_URL}}admin/css/base.css'
/>
<link
rel=
"stylesheet"
type=
"text/css"
href=
'{{STATIC_URL}}admin/css/forms.css'
/>
<link
rel=
"stylesheet"
type=
"text/css"
href=
'{{STATIC_URL}}admin/css/login.css'
/>
{% endif %}
<style>
.form-row
{
border-bottom
:
0.25em
!important
}
</style>
<link
rel=
"stylesheet"
type=
"text/css"
href=
'{% get_static_prefix %}css/djangorestframework.css'
/>
</head>
<body
class=
"login"
>
<div
id=
"container"
>
<div
id=
"container"
>
<div
id=
"header"
>
<div
id=
"branding"
>
<h1
id=
"site-name"
>
Django REST framework
</h1>
</div>
</div>
<div
id=
"content"
class=
"colM"
>
<div
id=
"content-main"
>
<form
method=
"post"
action=
"{% url djangorestframework.utils.staticviews.api_login %}"
id=
"login-form"
>
{% csrf_token %}
<div
id=
"content"
class=
"colM"
>
<div
id=
"content-main"
>
<form
method=
"post"
action=
"{% url djangorestframework.utils.staticviews.api_login %}"
id=
"login-form"
>
{% csrf_token %}
<div
class=
"form-row"
>
<label
for=
"id_username"
>
Username:
</label>
{{ form.username }}
</div>
...
...
@@ -36,19 +29,16 @@
<div
class=
"form-row"
>
<label>
</label><input
type=
"submit"
value=
"Log in"
>
</div>
</form>
<script
type=
"text/javascript"
>
document
.
getElementById
(
'id_username'
).
focus
()
</script>
</div>
</form>
<script
type=
"text/javascript"
>
document
.
getElementById
(
'id_username'
).
focus
()
</script>
</div>
<br
class=
"clear"
>
</div>
<div
id=
"footer"
></div>
</div>
</body>
</div>
</body>
</html>
djangorestframework/tests/mixins.py
View file @
c04cb514
...
...
@@ -275,3 +275,12 @@ class TestPagination(TestCase):
self
.
assertTrue
(
'foo=bar'
in
content
[
'next'
])
self
.
assertTrue
(
'another=something'
in
content
[
'next'
])
self
.
assertTrue
(
'page=2'
in
content
[
'next'
])
def
test_duplicate_parameters_are_not_created
(
self
):
""" Regression: ensure duplicate "page" parameters are not added to
paginated URLs. So page 1 should contain ?page=2, not ?page=1&page=2 """
request
=
self
.
req
.
get
(
'/paginator/?page=1'
)
response
=
MockPaginatorView
.
as_view
()(
request
)
content
=
json
.
loads
(
response
.
content
)
self
.
assertTrue
(
'page=2'
in
content
[
'next'
])
self
.
assertFalse
(
'page=1'
in
content
[
'next'
])
examples/settings.py
View file @
c04cb514
# Settings for djangorestframework examples project
import
django
import
os
DEBUG
=
True
...
...
@@ -84,19 +85,17 @@ TEMPLATE_DIRS = (
# Don't forget to use absolute paths, not relative paths.
)
# for loading initial data
##SERIALIZATION_MODULES = {
# 'yml': "django.core.serializers.pyyaml"
#}
if
django
.
VERSION
<
(
1
,
3
):
staticfiles
=
'staticfiles'
else
:
staticfiles
=
'django.contrib.staticfiles'
INSTALLED_APPS
=
(
'django.contrib.auth'
,
'django.contrib.contenttypes'
,
'django.contrib.sessions'
,
'django.contrib.sites'
,
'django.contrib.staticfiles'
,
staticfiles
,
'django.contrib.messages'
,
'djangorestframework'
,
...
...
examples/urls.py
View file @
c04cb514
from
django.conf.urls.defaults
import
patterns
,
include
,
url
from
django.conf
import
settings
from
django.conf.urls.defaults
import
patterns
,
include
from
sandbox.views
import
Sandbox
from
django.contrib.staticfiles.urls
import
staticfiles_urlpatterns
try
:
from
django.contrib.staticfiles.urls
import
staticfiles_urlpatterns
except
ImportError
:
# Django <= 1.2
from
staticfiles.urls
import
staticfiles_urlpatterns
urlpatterns
=
patterns
(
''
,
(
r'^$'
,
Sandbox
.
as_view
()),
...
...
setup.py
100644 → 100755
View file @
c04cb514
#!/usr/bin/env
/
python
#!/usr/bin/env
python
# -*- coding: utf-8 -*-
from
setuptools
import
setup
import
re
import
os
import
sys
import
os
,
re
path
=
os
.
path
.
join
(
os
.
path
.
dirname
(
__file__
),
'djangorestframework'
,
'__init__.py'
)
init_py
=
open
(
path
)
.
read
()
VERSION
=
re
.
match
(
"__version__ = '([^']+)'"
,
init_py
)
.
group
(
1
)
def
get_version
(
package
):
"""
Return package version as listed in `__version__` in `init.py`.
"""
init_py
=
open
(
os
.
path
.
join
(
package
,
'__init__.py'
))
.
read
()
return
re
.
match
(
"__version__ = ['
\"
]([^'
\"
]+)['
\"
]"
,
init_py
)
.
group
(
1
)
def
get_packages
(
package
):
"""
Return root package and all sub-packages.
"""
return
[
dirpath
for
dirpath
,
dirnames
,
filenames
in
os
.
walk
(
package
)
if
os
.
path
.
exists
(
os
.
path
.
join
(
dirpath
,
'__init__.py'
))]
def
get_package_data
(
package
):
"""
Return all files under the root package, that are not in a
package themselves.
"""
walk
=
[(
dirpath
.
replace
(
package
+
os
.
sep
,
''
,
1
),
filenames
)
for
dirpath
,
dirnames
,
filenames
in
os
.
walk
(
package
)
if
not
os
.
path
.
exists
(
os
.
path
.
join
(
dirpath
,
'__init__.py'
))]
filepaths
=
[]
for
base
,
filenames
in
walk
:
filepaths
.
extend
([
os
.
path
.
join
(
base
,
filename
)
for
filename
in
filenames
])
return
{
package
:
filepaths
}
version
=
get_version
(
'djangorestframework'
)
if
sys
.
argv
[
-
1
]
==
'publish'
:
os
.
system
(
"python setup.py sdist upload"
)
print
"You probably want to also tag the version now:"
print
" git tag -a
%
s -m 'version
%
s'"
%
(
version
,
version
)
print
" git push --tags"
sys
.
exit
()
setup
(
name
=
'djangorestframework'
,
version
=
VERSION
,
url
=
'http://django-rest-framework.org'
,
download_url
=
'http://pypi.python.org/pypi/djangorestframework/'
,
license
=
'BSD'
,
description
=
'A lightweight REST framework for Django.'
,
author
=
'Tom Christie'
,
author_email
=
'tom@tomchristie.com'
,
packages
=
[
'djangorestframework'
,
'djangorestframework.templatetags'
,
'djangorestframework.tests'
,
'djangorestframework.runtests'
,
'djangorestframework.utils'
],
package_dir
=
{
'djangorestframework'
:
'djangorestframework'
},
package_data
=
{
'djangorestframework'
:
[
'templates/*'
,
'static/*'
]},
test_suite
=
'djangorestframework.runtests.runcoverage.main'
,
name
=
'djangorestframework'
,
version
=
version
,
url
=
'http://django-rest-framework.org'
,
download_url
=
'http://pypi.python.org/pypi/djangorestframework/'
,
license
=
'BSD'
,
description
=
'A lightweight REST framework for Django.'
,
author
=
'Tom Christie'
,
author_email
=
'tom@tomchristie.com'
,
packages
=
get_packages
(
'djangorestframework'
),
package_data
=
get_package_data
(
'djangorestframework'
),
test_suite
=
'djangorestframework.runtests.runcoverage.main'
,
install_requires
=
[
'URLObject>=0.6.0'
],
classifiers
=
[
classifiers
=
[
'Development Status :: 4 - Beta'
,
'Environment :: Web Environment'
,
'Framework :: Django'
,
...
...
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